【问题标题】:how to define a function from a string using python如何使用python从字符串定义函数
【发布时间】:2011-08-20 16:17:00
【问题描述】:

这是我的代码:

a = \
'''def fun():\n
    print 'bbb'
'''
eval(a)

fun()

但它显示错误:

Traceback (most recent call last):
  File "c.py", line 8, in <module>
    eval(a)
  File "<string>", line 1
    def fun():
      ^
SyntaxError: invalid syntax

那我该怎么办,

谢谢

【问题讨论】:

  • 为什么需要 eval() ?

标签: python string function


【解决方案1】:

eval() 带有字符串参数仅用于表达式。如果要执行语句,请使用exec

exec """def fun():
  print 'bbb'
"""

但在您这样做之前,请考虑您是否真的需要动态代码。到目前为止,大多数事情都可以在没有的情况下完成。

【讨论】:

  • 在 Python3 中,这现在是一个函数。您可能需要传入一个假的 locals/globals 字典,对一个已知的魔法值执行分配,然后执行 fun = myFakeLocals['magic_value']
  • @ninjagecko:他的代码使用的是 Python 2 语法,所以我认为他希望用同一种方言做出回应。不过,将“移植”到 Python 3 很简单,只需添加括号即可。也不需要传入 locals/globals。
  • 哎呀,确实你说得很对;如果您事先不知道 fun 的名称,我会将其与 locals()[functionName] 的替代方法混淆
  • eval 不仅仅用于表达式;只是str 参数必须是表达式,但它也可以采用任意复杂度的代码对象。如果你将它与compile 混合,你可以eval 任意代码,例如eval(compile(mystr, '&lt;string&gt;', 'exec')) 工作正常(与exec 不同,在 Python 2 和 Python 3 上的工作原理相同)。
  • “但是在你这样做之前,想想你是否真的需要动态代码。到目前为止,大多数事情都可以在没有的情况下完成。”,是的,否则我会写 VBScript。 “到目前为止,大多数事情都可以在没有的情况下完成。”,并且可以通过更可并行化来更好地完成(如果 C 内置了函数到 shellcode 预编译器,那么在不诉诸高级语言或为每个线程进程创建一个全局函数),而不是用只使用一次的东西来混淆全局范围。
【解决方案2】:

Eval 只计算表达式,而 exec 执行语句。

所以你尝试这样的事情

a = \
'''def fun():\n
    print 'bbb'
'''
exec a

fun()

【讨论】:

    【解决方案3】:

    非表达式eval参数必须先compile-ed; str 仅作为表达式处理,因此完整的语句和任意代码都需要compile

    如果和compile混用,可以eval任意代码,例如:

    eval(compile('''def fun():
        print('bbb')
    ''', '<string>', 'exec'))
    

    上述工作正常,并且在 Python 2 和 Python 3 上的工作方式相同,这与 exec(在 Py2 中是关键字,在 Py3 中是函数)不同。

    【讨论】:

    • 在 python 3.7 中执行此操作返回 None 而不是函数对象。
    • @Jonno_FTW:它不应该返回它(def 不是一个表达式,它不会产生任何可分配的东西),它只是将它添加到当前范围(如果在函数内,则为本地,否则全局,您可以选择为全局或本地传递备用dicts)。 eval 仅在与字符串或 'eval' 模式下的 compile 一起使用时才会产生有用的返回值;在'single''exec' 模式下,它不计算表达式。
    【解决方案4】:

    如果您的逻辑非常简单(即一行),您可以评估 lambda 表达式:

    a = eval("lambda x: print('hello {0}'.format(x))")
    a("world") # prints "hello world"
    

    正如其他人所说,如果可以的话,可能是best to avoid eval

    【讨论】:

      猜你喜欢
      • 2019-09-18
      • 2010-10-15
      • 2021-07-15
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多