eval在python中是什么意思_如何在Python中使⽤eval?
Python中的 eval是什么?
在Python中,我们有许多内置⽅法,这些⽅法对于使Python成为所有⼈的便捷语⾔⾄关重要,⽽eval是其中⼀种。eval函数的语法如下:
eval(expression, globals, locals)
如上所⽰,eval函数采⽤三个参数:expression –需要⼀个字符串,该字符串将被解析并评估为Python表达式
globals(可选)–⼀个字典,⽤于指定可⽤的全局⽅法和变量。
locals(可选)-另⼀个字典,⽤于指定可⽤的本地⽅法和变量。
稍后将在本⽂中显⽰对global(全局变量)s和locals(本地变量)的使⽤。
eval在Python中做什么?
eval函数解析expression参数并将其评估为python表达式。换句话说,我们可以说这个函数解析了传递
网页float是什么意思给它的表达式并在程序中运⾏python expression(code)。
为了评估基于字符串的表达式,Python的eval函数运⾏以下步骤:解析表达式
编译成字节码
将其评估为Python表达式
返回评估结果
这意味着当我们将任何python表达式作为“字符串”传递给eval函数时,它会评估该表达式并将结果返回为整数或浮点数。以下是⼀些简单的⽰例,它们将使您更加清楚。
这是在Python中使⽤eval将字符串转换为整数,复数或浮点数的简单⽅法:
num =“ 23”
float_num =“ 53.332”
complex_num =“ 2 + 3j”
str1 =“ Not number”
print(eval(num),type(eval(num)))
print(eval(float_num),type( eval(float_num)))
print(eval(complex_num),type(eval(complex_num)))
print(eval(str1),type(eval(str1))) code>
OUTPUT:
23
53.332
(2+3j)
Traceback (most recent call last):
File "main.py", line 8, in
print(eval(str1),type(eval(str1)))
File "", line 1
Not number
^
SyntaxError: unexpected EOF while parsing
如您所见,eval函数能够识别字符串中的表达式并将其转换为相应的类型。但是,当我们仅传递字符和字母时,它返回了⼀个错误。这应该清楚eval的实际作⽤。
这⾥有更多的例⼦,其中我们不仅仅涉及类型转换,实际上我们看到了eval函数评估字符串中的表达式。
我们还可以使⽤eval求解数学表达式:
expr =“(2+(3 * 2))/ 2”
print(eval(expr)) code>
OUTPUT:
4.0
我们甚⾄可以在字符串中使⽤变量名,Python还将对它们进⾏评估,如下所⽰
num=10
expr="(2+(3*2))/2 + num"
print(eval(expr))
OUTPUT:
14.0
我们还可以在字符串内部使⽤内置函数,如下所⽰:
print(eval("sum([8, 16, 34])"))
OUTPUT:
58
为了更好地了解eval函数,让我们看看如果将表达式⽤两个字符串括起来,它将如何响应,如下所⽰:
#string in another string
expr="'2+3'"
print(eval(expr))
print(eval(eval(expr)))
OUTPUT:
2+3
5
因此,第⼀个eval函数只是返回字符串中的表达式,但是在另⼀个eval函数中使⽤eval时,我们得到了表达式的答案。
如何在python中使⽤eval ?
在上⼀节中,我们已经了解了如何使⽤eval函数,但是在这⾥,我们将了解eval函数的其他参数如何影响其⼯作。因此,Python中的eval 还有两个参数,即viz-globals和locals。
全局变量是当前全局范围或命名空间中可⽤的对象。您可以从代码中的任何位置访问它们。
在执⾏时,传递给字典中全局变量的所有对象将对eval()可⽤。请查看以下⽰例,该⽰例显⽰了如何使⽤⾃定义词典为eval函数提供全局名称空间:
num1 = 100 # A global variable
print(eval("num1 + 100", {"num1": num1}))
num2 = 200 # Another global variable
print(eval("num1 + num2", {"num1": num1,"num2": num2}))
print(eval("num1 + num2", {"num1": num1}))
OUTPUT:
200
300
Traceback (most recent call last):
File "main.py", line 5, in
print(eval("num1 + num2", {"num1": num1}))
File "", line 1, in
NameError: name 'num2' is not defined
如您在上⾯的⽰例中看到的,⾸先eval只能访问num1和num2,但是当我从globals字典中删除num2时,它抛出了⼀个错误,因为它现在⽆法识别num2。
但是,为什么在我甚⾄没有将值传递给globals参数的上述⽰例中都没有发⽣这种错误?
事实证明,当您在不提供globals参数的情况下调⽤eval函数时,该函数将使⽤globals()函数返回的字典作为其全局命名空间来评估表达式。
因此,在上⾯的⽰例中,我们可以⾃由访问所有变量,因为它们是当前全局范围中包含的全局变量。
现在,如果将空字典传递给全局变量会发⽣什么,让我们看看:
a=2
print(eval("sum([2, 2, 2])", {}))
print(eval("sum([a, 2, 2])", {}))
OUTPUT:
6
Traceback (most recent call last):
File "main.py", line 3, in
print(eval("sum([a, 2, 2])", {}))
File "", line 1, in
NameError: name 'a' is not defined
因此,eval函数可以成功识别函数和,但⽆法识别对象“ a”,因此返回错误。
当我们向全局变量提供⾃定义词典时,它包含键“ __builtins__”的值,但如果不包含该值,则在解析表达式之前,将⾃动在“
__builtins__”下插⼊对内置字典的引⽤。这样可以确保eval()函数在评估表达式时将完全访问所有Python的内置名称。这说明了在上⾯的⽰例中,如何通过eval识别函数和。
现在让我们看看什么是局部变量以及它们如何扩展eval函数的功能。与全局变量不同,局部对象在函数内部声明,不能在函数外部访问。
类似地,locals参数采⽤⼀个字典,在字典中我们添加了⼀些对象,⽽eval()函数将这些对象视为本地对象。请看下⾯的例⼦:
print(eval("sum([a, 2, 2])",{}, {"a":2}))
print(a)
OUTPUT:
6
Traceback (most recent call last):
File "main.py", line 2, in
print(a)
NameError: name 'a' is not defined
请注意,要向本地⼈提供字典,您⾸先需要向全局⼈提供字典。不能将关键字参数与eval()⼀起使⽤
这似乎令⼈困惑,但是在下⾯的⽰例中,我同时使⽤了globals和locals参数,您将看到它们如何影响结果。
print(eval("abs(-1)"))
#By keeping __builtins__":None,eval will recognise no in-buiilt function
print(eval('abs(-1)',{"__builtins__":None}))
OUTPUT:
1
Traceback (most recent call last):
File "main.py", line 1, in
print(eval('abs(-1)',{"__builtins__":None}))
File "", line 1, in
TypeError: 'NoneType' object is not subscriptable
现在,我们希望该函数在eval函数中起作⽤,因此将其添加到本地字典中。现在,eval函数可以识别abs函数,⽽不能识别任何其他函数。print(eval('abs(-1)',{"__builtins__":None},{"abs":abs}))
OUTPUT:
1
全局变量和局部变量之间的主要实际区别是,如果该密钥尚不存在,Python会⾃动将“ __builtins__”键插⼊全局变量。⽆论是否为全局变量提供⾃定义词典,都会发⽣这种情况。另⼀⽅⾯,如果向本地⼈提供⾃定义词典,则在执⾏eval函数期间该词典将保持不变。
评估的局限性
Python中的eval()很有⽤,但也有重要的安全隐患。eval函数被认为是不安全的,因为它允许您或其他⽤户动态执⾏任意Python代码。那对我们有什么影响?
假设您正在服务器上运⾏的应⽤程序中要求⽤户输⼊。现在,如果您在输⼊上使⽤eval函数,则⽤户可以访问服务器本⾝。⽤户可以像这样传递⼀些可疑的代码:
__ import __('subprocess')。getoutput('rm –rf *')
code>
上⾯的代码将删除应⽤程序当前⽬录中的所有⽂件,这肯定会影响我们。
因此,最好避免使⽤eval函数,但是如果仍然要使⽤eval函数,我们可以借助globals和locals参数来限制其功能。正如我们在上⼀节中看到的那样,我们限制eval函数,使其只能使⽤python的abs函数。
例如,假设我有⼀个应⽤程序,可以在给定数字或所有给定数字的总和中到最⼩值。像这样使⽤eval的最⽅便⽅法
print(eval(input()))
#input:sum([1,3,4])
#output:8
#input:min([1,3,4])
#output:1 code>
但是,这是⼀种不好的编程⽅式。我们⽆法控制⽤户的输⼊内容,因此我们可以利⽤globals和locals参数,使得eval不能识别sum()和
min()以外的函数。这肯定会和上⾯的代码做同样的事情,但是要安全得多。
print(eval(input(),{“ __ builtins __”:None},{“ min”:min,“ sum”:sum})) code>
希望⼤家可以通过本⽂了解到Python中的 eval函数,如果您想了解更多有关python案例实操,建议阅读“Python经典80案例实操”

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。