在我正在阅读的Python书籍中,它一直使用代码eval(input('blah'))

我阅读了文档,我理解了它,但我仍然不明白它是如何改变input()函数的。

它能做什么?有人能解释一下吗?


当前回答

如果您想将计算字符串限制为简单的字面量,另一个选项是使用ast.literal_eval()。一些例子:

import ast

# print(ast.literal_eval(''))          # SyntaxError: unexpected EOF while parsing
# print(ast.literal_eval('a'))         # ValueError: malformed node or string
# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax
# print(ast.literal_eval('1+1'))       # 2: but only works due to a quirk in parser
# print(ast.literal_eval('1*1'))       # ValueError: malformed node or string
print(ast.literal_eval("{'a':1}"))     # {'a':1}

从文档中可以看出:

Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None. This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.

至于为什么如此有限,从邮件列表中可以看出:

允许使用字面量的运算符表达式是可能的,但是比当前的实现要复杂得多。简单的实现是不安全的:你可以毫不费力地诱导出基本上无限的CPU和内存使用(尝试“9**9**9”或“[None] *9**9”)。 至于实用性,这个函数用于“读回”由repr()字符串化的文字值和容器。例如,可以使用类似于JSON但比JSON更强大的格式进行序列化。

其他回答

Eval()将字符串解释为代码。这么多人警告您不要使用它的原因是因为用户可以使用它作为在计算机上运行代码的选项。如果你导入了eval(input())和os,人们可以在input() os中输入。system('rm -R *')将删除主目录下的所有文件。(假设您有unix系统)。使用eval()是一个安全漏洞。如果需要将字符串转换为其他格式,请尝试使用类似int()的方法。

eval函数允许Python程序在自身内部运行Python代码。

Eval示例(交互式shell):

>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1

在Python 2中。在Python 3中,x input(…)等价于eval(raw_input(…))。x raw_input被重命名为input,我怀疑这导致了您的困惑(您可能正在查看Python 2.x中的输入文档)。此外,eval(input(…))在Python 3中可以很好地工作。x,但在Python 2中会引发TypeError。

在这种情况下,eval用于将输入返回的字符串强制转换为表达式并进行解释。通常这被认为是不好的做法。

如果您想将计算字符串限制为简单的字面量,另一个选项是使用ast.literal_eval()。一些例子:

import ast

# print(ast.literal_eval(''))          # SyntaxError: unexpected EOF while parsing
# print(ast.literal_eval('a'))         # ValueError: malformed node or string
# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax
# print(ast.literal_eval('1+1'))       # 2: but only works due to a quirk in parser
# print(ast.literal_eval('1*1'))       # ValueError: malformed node or string
print(ast.literal_eval("{'a':1}"))     # {'a':1}

从文档中可以看出:

Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None. This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.

至于为什么如此有限,从邮件列表中可以看出:

允许使用字面量的运算符表达式是可能的,但是比当前的实现要复杂得多。简单的实现是不安全的:你可以毫不费力地诱导出基本上无限的CPU和内存使用(尝试“9**9**9”或“[None] *9**9”)。 至于实用性,这个函数用于“读回”由repr()字符串化的文字值和容器。例如,可以使用类似于JSON但比JSON更强大的格式进行序列化。

也许是一个阅读一行文字并解释它的误导性例子。

尝试eval(input())并输入“1+1”-这应该打印2。Eval求表达式的值。