Python eval()与exec()函数详解:语法、区别与安全限制
本文详解Python内置函数eval()与exec()的语法结构、返回值差异及应用场景。重点讲解如何通过globals和locals参数控制命名空间,避免变量污染,并指出动态执行字符串代码的安全风险及限制执行范围的方法。
eval() 和 exec() 均为 Python 内置函数,功能相似,均可执行以字符串形式提供的 Python 代码,作用类似于一个 Python 解释器。两者的核心区别在于:eval() 执行后会返回结果,而 exec() 执行后不返回任何结果。
eval()和exec()的用法
eval() 函数的语法格式为:
eval(expression, globals=None, locals=None, /)而 exec() 函数的语法格式如下:
exec(expression, globals=None, locals=None, /)可以看出,两者语法结构除函数名外基本一致,各参数具体含义如下:
1、expression:该参数为字符串,代表要执行的语句。该语句受后续两个字典类型参数 globals 和 locals 的限制,仅当 globals 字典和 locals 字典作用域内的函数和变量才能被执行。 2、globals:该参数管控全局命名空间,即 expression 可使用全局命名空间中的函数。若仅提供了 globals 参数而未提供自定义的 builtins,系统会将当前环境中的 builtins 复制至提供的 globals 中,随后进行计算;若未提供 globals 参数,则使用 Python 的全局命名空间。 3、locals:该参数管控局部命名空间,与 globals 类似。当 globals 和 locals 中存在重复或冲突时,以 locals 为准。若未提供 locals 参数,则默认值为 globals。
两者的主要区别在于执行结果:eval() 执行后会返回结果,而 exec() 执行后不返回结果。
eval() 和 exec() 函数的应用场景 在 Python 服务端程序开发中,这两个函数应用广泛。例如,客户端向服务端发送一段字符串代码,服务端无需关心具体内容,直接通过 eval() 或 exec() 执行即可。这种设计降低了服务端与客户端的耦合度,使系统更易于扩展。
以 TensorFlow 框架为例,其静态图的实现原理与此类似:
TensorFlow 中先将张量定义在一个静态图里,这就相当将键值对添加到字典里一样;
TensorFlow 中通过 session 和张量的 eval() 函数来进行具体值的运算,就当于使用 eval() 函数进行具体值的运算一样。需要注意的是,在使用 eval() 或 exec() 处理请求代码时,这两个函数常被黑客利用,成为执行系统级命令的入口点,进而攻击网站。解决方法是:通过设置其命名空间中的可执行函数,来限制 eval() 和 exec() 的执行范围。
python中的exec()函数和eval()函数
exec()函数
exec 函数用于执行存储在字符串中的 Python 语句。
>>> exec("x=1")
>>> x
1但有时直接这样执行可能会污染我们的命名空间,如下例所示,我们使用 Python 内置的 abs 函数求绝对值。
>>> abs(-1)
1
>>> exec("abs='xyz'")
>>> abs(-1)
File "<stdin>", line 1, in <module>
TypeError: "str" object is not callable在执行 abs 函数时报错,类型为 TypeError,提示字符串类型对象不能被调用。原因在于我们使用 exec 函数将字符串 'xyz' 赋值给了 abs,此时 abs 不再表示求绝对值的函数。为防止此类情况,调用 exec 函数时可传递第二个参数——命名空间,即一个字典。
>>> abs(-1)
1
>>> scope = {}
>>> exec("abs='xyz'", scope)
>>> abs(-1)
1
>>>scope['abs']
'xyz'这样,通过 exec 执行赋值语句创建的变量就位于 scope 中,不会污染全局命名空间。
eval()函数
eval 用于执行存储在字符串中的 Python 表达式。
>>> eval("1+2+3+4+5")
15与 exec 函数一样,我们也可以给 eval 函数提供命名空间。
总结
1、exec 函数执行的是 Python 语句,没有返回值;eval 函数执行的是 Python 表达式,有返回值;
2、exec 函数和 eval 函数都可以传入命名空间作为参数。实际上,可以向 exec 函数和 eval 函数提供两个命名空间,其函数定义为:
exec(source, globals=None, locals=None)
eval(source, globals=None, locals=None)
其中 globals 和 locals 都是可选参数,globals 表示全局命名空间,必须是字典;locals 表示局部命名空间,可以是任何映射。
3、需要注意的是,exec 函数和 eval 函数都是将用户提供的字符串作为代码执行,无法控制代码的行为,会带来严重的安全隐患,使用时要慎重。
到此这篇关于 Python eval() 和 exec() 函数的文章就介绍到这了,更多相关 Python eval() 和 exec() 函数内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









