Python 的 eval() 有什么作用?

2024-12-06 08:40:00
admin
原创
99
摘要:问题描述:我正在阅读的有关 Python 的书反复显示如下代码eval(input('blah'))。这究竟如何修改调用的结果input?另请参阅: 为什么使用“eval”是一种不好的做法?以了解使用或不受信任的输入(即:任何部分受用户控制而不是程序控制的事物)所产生的严重安全风险。eval`exec`另请参...

问题描述:

我正在阅读的有关 Python 的书反复显示如下代码eval(input('blah'))

这究竟如何修改调用的结果input


另请参阅: 为什么使用“eval”是一种不好的做法?以了解使用或不受信任的输入(即:任何部分受用户控制而不是程序控制的事物)所产生的严重安全风险。eval`exec`

另请参阅: 如何在纯 Python 中沙盒化 Python?简而言之,正确地做到这一点总是比选择合适的工具而不是eval或更难exec

请参阅使用 python 的 eval() 与 ast.literal_eval()来了解可能更安全的技术。

请参阅如何在 Python 3 中使用 raw_input?以了解书籍可能包含此类代码的背景知识,或者 OP 最初可能期望结果input不需要进一步处理的原因。


解决方案 1:

eval 函数让 Python 程序在其内部运行 Python 代码。

eval 示例(交互式 shell):

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

解决方案 2:

eval()将字符串解释为代码。之所以有这么多人警告您不要使用此功能,是因为用户可以将其用作在计算机上运行代码的选项。如果您导入了eval(input())os,则有人可以输入 ,input() os.system('rm -R *')这将删除您主目录中的所有文件。(假设您使用的是 unix 系统)。使用eval()是一个安全漏洞。如果您需要将字符串转换为其他格式,请尝试使用可以执行此操作的东西,例如int()

解决方案 3:

如文档中所述,eval()还具有globalslocals关键字参数,可用于限制可通过eval函数使用的函数。例如,如果您加载一个新的 Python 解释器,locals()globals()将相同,如下所示:

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

模块中的某些函数肯定builtins会对系统造成严重损害。但可以阻止我们不想使用的任何内容。假设我们想构建一个列表来表示系统上可用核心的范围。对我来说,我有 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可以安全地使用它来获得巨大的价值。

注意:

这些的另一个很酷的地方kwargs是,您可以开始使用简写来编写代码。假设您使用eval作为管道的一部分来执行一些导入的文本。文本不需要有确切的代码,它可以遵循一些模板文件格式,并且仍然可以执行您想要的任何内容。例如:

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

解决方案 4:

在 Python 2.x 中input(...)相当于eval(raw_input(...)),在 Python 3.x 中raw_input被重命名为input,我怀疑这会导致您混淆(您可能正在查看 Python 2.x 中的文档input)。此外,eval(input(...))在 Python 3.x 中可以正常工作,但在 Python 2 中会引发TypeError

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

解决方案 5:

如果您想将评估字符串限制为简单文字,另一个选择是使用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}

来自文档:

安全地评估包含 Python 文字或容器显示的表达式节点或字符串。提供的字符串或节点只能以下 Python 文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔值和 None。

这可用于安全地评估包含来自不受信任来源的 Python 值的字符串,而无需自己解析这些值。它无法评估任意复杂的表达式,例如涉及运算符或索引的表达式。

至于为什么它如此有限,来自邮件列表:

允许使用文字的运算符表达式是可能的,但比当前实现复杂得多。简单的实现并不安全:您可以毫不费力地引发基本上不受限制的 CPU 和内存使用(尝试“999”或“[None] 9*9”)。

至于实用性,此函数可用于“读回”由 repr() 字符串化的文字值和容器。例如,这可以用于以与 JSON 类似但功能更强大的格式进行序列化。

解决方案 6:

eval(),顾名思义,对传递的参数进行求值。

raw_input()现在已input()包含在 Python 3.x 版本中。因此,最常见的使用示例是使用它来提供Python 2.x 版本中提供的eval()功能。input()

raw_input将用户输入的数据以字符串形式返回,而input 则评估输入数据的值并返回它。

eval(input("bla bla"))因此复制了 2.x 中的功能input(),即评估用户输入的数据。

简而言之:eval()评估传递给它的参数并eval('1 + 1')返回 2。

解决方案 7:

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

尝试eval(input())并输入"1+1"- 这应该会打印2。Eval 评估表达式。

解决方案 8:

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

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

在这里阅读有关 eval 的更多信息。

解决方案 9:

的一个有用应用eval()是从字符串中评估 Python 表达式。例如,从文件加载字典的字符串表示形式:

running_params = {"Greeting": "Hello, "}
fout = open("params.dat", 'w')
fout.write(repr(running_params))
fout.close()

将其作为变量读出并编辑:

fin = open("params.dat", 'r')
diction = eval(fin.read())
diction["Greeting"] += "World!"
fin.close()
print diction

输出:

{'Greeting': 'Hello, World!'}

解决方案 10:

如果用户输入数字值,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

解决方案 11:

eval() 函数接受三个参数来计算并返回值。

语法: eval(expression, globals, locals)

expression #python3 表达式的字符串

globals (可选) #dictionary

locals (可选) #dictionary

您经常使用的常见用例是

x="{'name':'abhi','mydict':{'sub':'python'}}"

y=dict(x)
print(y,type(y)) # ValueError: dictionary update sequence element #0 has length 1; 2 is required
z=eval(x)
print(z,type(z)) #{'name': 'abhi', 'mydict': {'sub': 'python'}} <class 'dict'>

解决方案 12:

eval()注意和的区别exec()

>>> exec("x=2")
>>> x
2
>>> eval("x=1")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    x=1
     ^
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   997  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   34  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   40  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   39  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   71  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用