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

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

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


当前回答

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 >

其他回答

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

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

如文档中所述,eval()还具有globals和locals关键字参数,可用于限制通过eval函数可用的函数。例如,如果你加载一个新的python解释器,locals()和globals()将是相同的,看起来像这样:

>>> globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
 '__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
 '__package__': None, '__name__': '__main__'}

在内置模块中,肯定有一些函数会对系统造成重大损害。但是我们可以屏蔽任何我们不想要的东西。假设我们想要构造一个列表来表示系统上可用内核的域。对于我来说,我有8个核心,所以我想要一个列表[1,8]。

>>> from os import cpu_count
>>> eval('[1, cpu_count()]')
[1, 8]

同样,所有__builtins__都是可用的。

>>> eval('abs(-1)')
1

让我们尝试阻止对任何全局变量的访问:

>>> eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable

我们已经有效地阻止了所有__builtins__函数,这样就为我们的系统带来了一定程度的保护。此时,我们可以开始添加回我们想要公开的函数。

>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable

现在我们有了可用的cpu_count函数,但仍然阻塞了我们不想要的一切。在我看来,这是超级强大的,显然从其他答案的范围,不是一个常见的实现。类似这样的东西有很多用途,只要处理正确,我个人认为eval可以安全地用于巨大的价值。

N.B.

关于这些kwarg的另一个很酷的地方是,您可以开始在代码中使用速记。假设您使用eval作为管道的一部分来执行一些导入的文本。文本不需要有精确的代码,它可以遵循一些模板文件格式,并仍然执行您想要的任何东西。例如:

>>> from os import cpu_count
>>> eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]

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

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

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

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

如果用户输入一个数值,input()将返回一个字符串。

>>> input('Enter a number: ')
Enter a number: 3
>>> '3'
>>> input('Enter a number: ')
Enter a number: 1+1
'1+1'

Eval()将计算返回值(或表达式),它是一个字符串,并返回整数/浮点数。

>>> eval(input('Enter a number: '))
Enter a number: 1+1
2
>>> 
>>> eval(input('Enter a number: '))
Enter a number: 3.14
3.14

但是,最好在这里使用更具体的工具,如int()或float()。

>>> float(input('Enter a number: '))
Enter a number: 3.14
3.14