【问题标题】:How to return value from exec in function?如何从函数中的exec返回值?
【发布时间】:2016-01-29 07:09:24
【问题描述】:

我试试:

def test(w,sli):
    s = "'{0}'{1}".format(w,sli)
    exec(s)
    return s

print test("TEST12344","[:2]")

返回 'TEST12344'[:2]

如何从函数中的exec返回值

【问题讨论】:

    标签: python string python-2.7 exec


    【解决方案1】:

    exec() 不仅计算表达式,还执行代码。您必须在exec() 调用中保存参考

    def test(w, sli):
        exec('s = "{}"{}'.format(w, sli))
        return s
    

    如果您只想计算表达式,请使用eval(),并保存对返回值的引用:

    def test(w,sli):
        s = "'{0}'{1}".format(w,sli)
        s = eval(s)
        return s
    

    但是,我建议尽可能避免在任何实际代码中使用 exec()eval()。如果您使用它,请确保您有充分的理由这样做。

    【讨论】:

    • 这在python 3中不起作用,给NameErrors
    • @Eric 从 OP 将print 用作语句而不是函数可以看出,这里没有使用 Python 3。
    • 你是对的,但我和其他偶然发现这个答案的用户越来越有可能使用 python 3 - 所以我留了个便条以节省他们尝试它的时间。
    【解决方案2】:

    考虑运行以下代码。

    code = """
    def func():
        print("std out")
        return "expr out"
    func()
    """
    

    在 Python 控制台上

    如果您在 python 控制台上运行func(),输出将类似于:

    >>> def func():
    ...     print("std out")
    ...     return "expr out"
    ...
    >>> func()
    std out
    'expr out'
    

    使用执行

    >>> exec(code)
    std out
    >>> print(exec(code))
    std out
    None
    

    如你所见,返回值为 None。

    带评估

    >>> eval(code)
    

    会产生错误。

    所以我做了我的 exec_with_return()

    import ast
    import copy
    def convertExpr2Expression(Expr):
            Expr.lineno = 0
            Expr.col_offset = 0
            result = ast.Expression(Expr.value, lineno=0, col_offset = 0)
    
            return result
    def exec_with_return(code):
        code_ast = ast.parse(code)
    
        init_ast = copy.deepcopy(code_ast)
        init_ast.body = code_ast.body[:-1]
    
        last_ast = copy.deepcopy(code_ast)
        last_ast.body = code_ast.body[-1:]
    
        exec(compile(init_ast, "<ast>", "exec"), globals())
        if type(last_ast.body[0]) == ast.Expr:
            return eval(compile(convertExpr2Expression(last_ast.body[0]), "<ast>", "eval"),globals())
        else:
            exec(compile(last_ast, "<ast>", "exec"),globals())
    
    exec_with_return(code)
    

    【讨论】:

    • 哇,这是我遇到的唯一一个问题,从 exec 命令返回 None begin 以及如何处理它。您的代码作为一个插件工作。添加了您的代码,更改了我的代码的 1 行,它的工作原理!
    • 我一直在创建一个模拟后端服务器来测试前端,我希望允许在服务器上执行任意 Python 表达式。这非常方便——从我的 HTTP API 中提供 IPython shell 的熟悉 eval 语义。谢谢!
    • 这里的想法很棒,这正是我实现一些类似于 Python 控制台工作方式的行为所需要的。但是,我想知道实现是否使它看起来比需要的更复杂。需要这两个副本是否有任何技术原因?如果它是 Expr,为什么不简单地将节点从 code_ast.body 中弹出?然后,无论哪种方式,code_ast 都可以简单地按原样执行。最后,如果我们确实弹出了最后一个节点,则可以将其转换为上述表达式并进行评估。
    【解决方案3】:

    我在 2020 年在 Python 3.8 中的发现

    在评估逻辑中:

    a="1+99"
    a=eval(a)
    print(a) # output: 100
    

    在执行逻辑中

    exec ("a=33+110")
    print(a) #output 143
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      相关资源
      最近更新 更多