为什么Python的eval()拒绝这个多行字符串,我该如何解决?

Chr*_*ard 11 python eval metaprogramming python-3.x

我试图评估以下制表符缩进的字符串:

'''for index in range(10):
        os.system("echo " + str(index) + "")
'''
Run Code Online (Sandbox Code Playgroud)

我明白了,"有一个错误:语法无效,第1行"

有什么抱怨的?我是否需要缩进以匹配eval()语句,或将其写入字符串文件或临时文件并执行该操作或其他内容?

谢谢,

Jor*_*ley 22

eval 评估类似的东西 5+3

exec 执行类似的东西 for ...

>>> eval("for x in range(3):print x")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for x in range(3):print x
      ^
SyntaxError: invalid syntax
>>> exec("for x in range(3):print x")
0
1
2
>>> eval('5+3')
8
Run Code Online (Sandbox Code Playgroud)


Ash*_*ary 13

要与eval您一起使用此类语句,应首先将它们转换为代码对象,使用compile():

In [149]: import os

In [150]: cc = compile('''for index in range(10):
    os.system("echo " + str(index) + "")''','abc','single')

In [154]: eval cc
--------> eval(cc)
0
Out[154]: 0
1
Out[154]: 0
2
Out[154]: 0
3
Out[154]: 0
4

In [159]: cc = compile("2+2", 'abc', 'single')  # works with simple expressions too 

In [160]: eval cc
--------> eval(cc)
Out[160]: 4


>>> help(compile)

compile(...)
    compile(source, filename, mode[, flags[, dont_inherit]]) -> code object

    Compile the source string (a Python module, statement or expression)
    into a code object that can be executed by the exec statement or eval().
    The filename will be used for run-time error messages.
    The mode must be 'exec' to compile a module, 'single' to compile a
    single (interactive) statement, or 'eval' to compile an expression.
    The flags argument, if present, controls which future statements influence
    the compilation of the code.
    The dont_inherit argument, if non-zero, stops the compilation inheriting
    the effects of any future statements in effect in the code calling
    compile; if absent or zero these statements do influence the compilation,
    in addition to any features explicitly specified.
Run Code Online (Sandbox Code Playgroud)

  • 一如既往的好答案和python的功能我不知道:) (2认同)

And*_*den 5

我们使用evaluate(eval)表达式和execute(exec)语句.

请参阅:表达式与声明.

表达式:评估值的东西.示例:1 + 2/x
语句:执行某些操作的代码行.示例:GOTO 100


Att*_*igh 5

(在将这样的代码投入生产之前,请参阅最后的默认安全警告!)

其他答案很好地说明了exec和之间的区别eval。

但是,我发现自己想像这样输入,x=1; y=2; x+y而不是强迫人们写:

def f():
   x = 1
   y = 2
   return x + y
Run Code Online (Sandbox Code Playgroud)

字符串操纵代码来构建这种功能是一项冒险的业务。

我最终使用以下方法:

def multiline_eval(expr, context):
    "Evaluate several lines of input, returning the result of the last line"
    tree = ast.parse(expr)
    eval_expr = ast.Expression(tree.body[-1].value)
    exec_expr = ast.Module(tree.body[:-1])
    exec(compile(exec_expr, 'file', 'exec'), context)
    return eval(compile(eval_expr, 'file', 'eval'), context)
Run Code Online (Sandbox Code Playgroud)

这将解析python代码;使用ast库重建除最后一行以外的所有内容的ast;最后一行,执行前者,评估后者。

安全警告

这是您必须附加的强制性安全警告eval。 非特权用户提供的Eval“ ing”和exec“ ing”代码当然是不安全的。在这些情况下,您可能更喜欢使用其他方法,或者考虑使用ast.literal_eval。eval并且和exec往往是不好的想法,除非你真的想给你的用户的Python的全部表达能力。