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

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

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


当前回答

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

其他回答

在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用于将输入返回的字符串强制转换为表达式并进行解释。通常这被认为是不好的做法。

eval()将传递的字符串计算为Python表达式并返回结果。例如,eval("1 + 1")解释并执行表达式"1 + 1",并返回结果(2)。

您可能感到困惑的一个原因是,您引用的代码涉及到一定程度的间接。内部函数调用(input)首先执行,因此用户会看到“blah”提示。让我们想象一下,它们以“1 + 1”(为了清晰起见,添加引号,在运行程序时不要键入它们)响应,输入函数返回该字符串,然后将其传递给外部函数(eval),后者解释字符串并返回结果(2)。

在这里阅读更多关于eval的内容。

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

Eval示例(交互式shell):

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

eval()函数接受三个参数,求值并返回值。 语法:eval(表达式,全局变量,局部变量) python3表达式的字符串 Globals(可选)#字典 Locals(可选)#字典 #你经常使用的常见用例是 x = "{“名称”:“abhi”,“mydict”:{“子”:python的}}” y=dict(x)print(y,type(y)) # ValueError:字典更新序列元素#0的长度为1;需要2 z = eval (x)打印(z,类型(z)) #{“名称”:“abhi”,“mydict”:{“子”:python的}}<类的dict >

如果您想将计算字符串限制为简单的字面量,另一个选项是使用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更强大的格式进行序列化。