我正在尝试评估以下制表符缩进的字符串:
'''for index in range(10):
os.system("echo " + str(index) + "")
'''
我知道,“出现了错误:语法无效,第1行”
抱怨什么?我是否需要缩进以匹配eval()语句,或将其写入字符串文件或临时文件并执行该文件或其他内容?
谢谢,
答案 0 :(得分: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
答案 1 :(得分:12)
要在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.
答案 2 :(得分:5)
请参阅:Expression Versus Statement。
表达式:评估值的东西。示例:1 + 2 / x
声明:执行某些操作的代码行。示例:GOTO 100
答案 3 :(得分:4)
(在将此类代码投入生产之前,请参阅最后的默认安全警告!)
其他答案很好地解释了exec
和eval
之间的区别。
尽管如此,我发现自己想要像x=1; y=2; x+y
这样输入,而不是强迫别人写:
def f():
x = 1
y = 2
return x + y
构建此类函数的代码字符串操作是一项有风险的业务。
我最终使用了以下方法:
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)
这解析python代码;使用ast库重建除最后一行之外的所有内容;和最后一行,执行前者并评估后者。
这是您必须附加到eval
的强制性安全警告。
Eval
由非特权用户提供的代码和exec
代码当然是不安全的。在这些情况下,您可能更喜欢使用其他方法,或考虑ast.literal_eval。 eval
和exec
往往是坏主意,除非你真的想让你的用户具有python的全部表现力。