• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于python:python冷知识之eval的用法

python 搞代码 4年前 (2022-02-20) 29次浏览 已收录 0个评论

eval()语法及应用

eval()办法会解析传入该办法的表达式,并且会在程序中运行解析后的表达式。换句话说,它会将一个字符串解析成代码来执行。


STNTAX
eval(expression, GLOBALS=None, LOCALS=None)

  • expression: 传入的表达式
  • GLOBALS: 全局办法或者变量的字典
  • LOCALS: 部分办法或者变量的字典

该办法返回表达式执行的后果。
接下来咱们来创立表达式并运行程序来评估该表达式。


USAGE

user_expr = raw_input("请输出一个对于变量a的表达式:")
a = int(raw_input("请输出变量a的值:"))
result = eval(user_expr)
print("result = {}".format(result))

OUTPUT

请输出一个对于变量a的表达式: a ** 2 + 1
请输出变量a的值: 3
result = 10

Security Issue With eval()
假如你导入了os模块,os模块提供了一种快捷的形式来操作诸如读写文件这样的操作系统函数。如果你容许用户应用eval(input())的形式输出一个值,用户可能会输出扭转系统文件的命令,甚至会输出像os.system('rm -rf *')这样的命令删除整个系统文件。那么,在你的代码中应用eval(input())来检查用户能够应用的办法和变量不失为一个好主见,你能够应用dir()办法来查看哪些办法和变量是可用的。

from math import *
print(eval('dir()'))

Output

['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'os', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

在eval()中限度可用办法和变量的应用

大多数状况下,在expression中应用的办法和变量都不是必须的,甚至会造成安全漏洞。你可能须要限度这些办法和变量的应用,你能够通过像eval()中传入globalslocals参数来达到这一目标。


1.省略globals和locals参数

如果globalslocals参数都被省略掉,那么expression会在以后范畴内执行,你能够应用上面的办法来查看可用的办法和变量

print(eval(dir()))

2.只传入globals参数

globals参数和locals参数(字典)别离作用于全局变量和局部变量。如果省略了locals字典,那么其默认值是globals字典。意思就是,globals字典会同时作用于全局变量和局部变量。

你能够应用python的内置办法globals()和locals()来别离查看以后的全局变量和局部变量。


3.传入一个空字典作为globals参数
from math import *
print(eval('dir()', {}))

# 上面的代码会抛出异样
print(eval('sqrt(25)', {}))

Output

['__builtins__']
Traceback (most recent call last):
  File "<string>", line 5, in <module>
    print(eval('sqrt(25)', {}))
  File "<string>", line 1, in <module>
NameError: name 'sqrt' is not defined

如果你传入一个空字典作为globals参数,那么只有__builtins__办法是可用的,即便咱们导入了math模块,expression也不能拜访任何math模块提供的办法。


4.指定某些办法可用
from math import *
print(eval('dir()', {'sqrt': sqrt, 'pow': pow}))

Output

['__builtins__', 'pow', 'sqrt']

在这里,expression只能应用sqrt()、pow()以及__builtins__办法。当然,你也能够依据你的爱好来扭转可用办法的名字:

from math import *
names = {'square_root': sqrt, 'power': pow}
print(eval('dir()', names))

# 在表达式中应用别名
print(eval('square_root(9)', names))

Output

['__builtins__', 'power', 'square_root']
3.0

在下面的例子中,如果尝试间接应用sqrt()办法,程序会抛出谬误。


5.限度built-ins的应用

你能够通过上面的办法限度expression__builtins__的应用:

eval(expression, {'__builtins__: None})

6.传入globals和globals参数
from math import *

a = 169
print(eval('sqrt(a)', {'__builtins__': None}, {'a': a, 'sqrt': sqrt}))

Output

13.0

在这个例子中,expression能并且只能应用sqrt()办法和变量a,其它的所有办法和变量都不可能应用。


通过globalslocals参数的传递来限度eval()的用法能够让你的代码更加平安,尤其是在应用用户通过input()办法给eval()的时候。

有时候,即便限度eval()可应用的办法和变量也不是平安的,当一个对象和它的的办法是可拜访的,简直能够做任何事,这时候惟一平安的办法就是验证用户输出的有效性。

整顿自:


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于python:python冷知识之eval的用法

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址