python3中eval函数用法使用简介


Posted in Python onAugust 02, 2019

python中eval函数的用法十分的灵活,这里主要介绍一下它的原理和一些使用的场合。

下面是从python的官方文档中的解释:

  The arguments are a string and optional globals and locals. If provided, globals must be a dictionary. If provided, locals can be any mapping object.

   The expression argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the globals and locals dictionaries as global and local namespace. If the globals dictionary is present and lacks ‘__builtins__', the current globals are copied into globals before expression is parsed. This means that expression normally has full access to the standard builtins module and restricted environments are propagated. If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where eval() is called. The return value is the result of the evaluated expression. Syntax errors are reported as exceptions. Example:

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

 This function can also be used to execute arbitrary code objects (such as those created by compile()). In this case pass a code object instead of a string. If the code object has been compiled with 'exec' as the mode argument, eval()‘s return value will be None.

   Hints: dynamic execution of statements is supported by the exec() function. The globals() and locals() functions returns the current global and local dictionary, respectively, which may be useful to pass around for use by eval() or exec().

   See ast.literal_eval() for a function that can safely evaluate strings with expressions containing only literals.

下面我做一下简单的翻译,有可能有一些翻译不好的地方,见谅。

函数原型:

eval(expression, globals=None, locals=None)

参数:

expression:这个参数是一个字符串,python会使用globals字典和locals字典作为全局和局部的命名空间,将expression当做一个python表达式(从技术上讲,是一个条件列表)进行解析和计算。

globals:这个参数管控的是一个全局的命名空间,也就是我们在计算表达式的时候可以使用全局的命名空间中的函数,如果这个参数被提供了,并且没有提供自定义的__builtins__,那么会将当前环境中的__builtins__拷贝到自己提供的globals里,然后才会进行计算。关于__builtins__,它是python的内建模块,也就是python自带的模块,不需要我们import就可以使用的,例如我们平时使用的int、str、abs等都在这个模块中。如果globals没有被提供,则使用python的全局命名空间。

locals:这个参数管控的是一个局部的命名空间,和globals类似,不过当它和globals中有重复的部分时,locals里的定义会覆盖掉globals中的,也就是当globals和locals中有冲突的部分时,locals说了算,它有决定权,以它的为准。如果locals没有被 提供的话,则默认为globals。

eval函数也可以被用来执行任意的代码对象(如那些由compile()创建的对象)。在这种情况下,expression参数是一个代码对象而不是一个字符串。如果代码对象已经被‘exec‘编译为模式参数,eavl()的返回值是None。

下面举一些例子进行讲解:

三个参数的使用:

1、在前两个参数省略的情况下,eval在当前的作用域执行:

a=10;
print(eval("a+1"))

执行结果为:11

在这种情况下,后两个参数省略了,所以eval中的a是前面的10。对于eval,它会将第一个expression字符串参数的引号去掉,然后对引号中的式子进行解析和计算。

2、在globals指定的情况下:

a=10;
g={'a':4}
print(eval("a+1",g))

执行结果为:5

这里面可能有点绕啊,初学者得理理清楚。在这次的代码中,我们在 eval中提供了globals参数,这时候eval的作用域就是g指定的这个字典了,也就是外面的a=10被屏蔽掉了,eval是看不见的,所以使用了a为4的值。

3、在 locals指定的情况下 :

a=10
b=20
c=30
g={'a':6,'b':8}
t={'b':100,'c':10}
print(eval('a+b+c',g,t))

执行的结果为:116

这里面就更有点绕人了,此次执行的结果中,a是6,b是100,c是10。我们首先来看一下,对于a为6我们是没有疑问的,因为在上个例子中已经说了,g会屏蔽程序中的全局变量的,而这里最主要的是为什么b是100呢?还记得我们在参数介绍的时候说过,当locals和globals起冲突时,locals是起决定作用的,这在很多编程语言里都是一样的,是作用域的覆盖问题,当前指定的小的作用域会覆盖以前大的作用域,这可以理解为一张小的纸盖在了一张大的纸上,纸是透明的,上面写的东西是不透明的,而它们重合的地方就可以理解成两个作用域冲突的地方,自然是小的显现出来了。

使用的场合

对于eval的使用,我们一定要确保第一个参数expression满足表达式的要求,它是可以被解析然后计算的。

s="abck"
print(eval(s))

执行的结果为:NameError: name 'abck' is not defined

对于当面的代码,我们可以看到,字符串s并不满足表达式的要求。当eval剥去了"abck"的外面的引号的时候,它会对它进行解析,然后满足要求后进行计算,然后它解析到的是abcd,请注意,程序报出的错误是NameError,也就是说,当它解析到这个表达式是不可以计算后,它就会查找它是不是一个变量的名字,如果是一个变量的名字,那么它会输出这个变量的内容,否则就会产生这种报错。

s="abck"
print(eval('s'))

执行的结果为:abck

对于这个代码,我们就可以看出来了,eval首先将‘s'的引号剥去,然后得到的是s,显然这个是不可以进行计算的,那么它就开始查找s是否是一个变量的名字,然后它一查找,果然s是一个字符串,所以程序输出了s中的内容。

在上面一直说到expression的要求,那么它到底是什么具体要求呢?下面仍然通过例子进行说明。

s='"sas"'
print(eval(s))

执行的结果为:sas

对于这个代码,我们继续分析,eval首先去除单引号,eval在执行的时候是只会去除同种类型的引号的,对于单引号和双引号它是加以区分的。eval去除单引号后得到了“sas”,这个时候程序解析到它是一个字符串,不可以计算,就输出了它。那么不禁想问,为什么上个例子中s="abck"会不行呢,这里面我们就可以看出区别了,一个是有引号括起来的,一个是没有的,引号括起来代表字符串,虽然不可以求值,但是是有意义的,可以进行输出,而没引号的便无法判断“身份”了,只能当做变量名进行解析,而abck并不是一个变量名,所以就报错了。

s='["a","b","c"]'
print(eval(s))

执行的结果为:['a', 'b', 'c']

对于这个程序就不多做解释了,eval去除引号后会检查到它是不可计算的,但它是一个列表,便输出了里面的内容。

a=10
b=20
c=30
s='[a,b,c]'
print(eval(s))

执行的结果为:[10, 20, 30]

对于这个程序的结果,是不是有点意外,这里需要说明的是,eval检查到列表的‘['‘]'符号时,是会对里面的元素进行解析的,这里a、b、c显然不是具体的数据,便去查找它们是否是变量名,然后确认是变量名后,用它们的内容替换掉它。

s='abs(10)'
print(eval(s))

执行的结果为:10

对于这个程序,我们举的是一个满足计算的一个表达式,当eval剥去s的引号后,得到abs(10),然后它会对进行解析,这个解析我们前面介绍eval的时候说过,它会使用globals的内建模块__builtins__进行解析的,在这个内建模块中是有abs这个函数的,所以对abs(10)进行了计算。

关于__builtins__模块中有哪些东西 ,我们可以这样查看:

print(dir(__builtins__))

执行结果为:

['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

在这里我们可以看见这个模块中所有的东西,eval在进行计算的时候也是在这里进行查找的

到这里,eval的解释说明就结束了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
PyCharm安装第三方库如Requests的图文教程
May 18 Python
python range()函数取反序遍历sequence的方法
Jun 25 Python
python统计字母、空格、数字等字符个数的实例
Jun 29 Python
解决使用pycharm提交代码时冲突之后文件丢失找回的方法
Aug 05 Python
pycharm恢复默认设置或者是替换pycharm的解释器实例
Oct 29 Python
Python3 修改默认环境的方法
Feb 16 Python
python把1变成01的步骤总结
Feb 27 Python
python使用pymongo操作mongo的完整步骤
Apr 13 Python
python 上下文管理器及自定义原理解析
Nov 19 Python
Python实现CNN的多通道输入实例
Jan 17 Python
Python龙贝格法求积分实例
Feb 29 Python
python利用platform模块获取系统信息
Oct 09 Python
Django用户认证系统 Web请求中的认证解析
Aug 02 #Python
Django用户认证系统 User对象解析
Aug 02 #Python
浅谈python3中input输入的使用
Aug 02 #Python
Pycharm连接远程服务器并实现远程调试的实现
Aug 02 #Python
在PyCharm的 Terminal(终端)切换Python版本的方法
Aug 02 #Python
Django单元测试工具test client使用详解
Aug 02 #Python
Django使用unittest模块进行单元测试过程解析
Aug 02 #Python
You might like
用PHP动态创建Flash动画
2006/10/09 PHP
ajax缓存问题解决途径
2006/12/06 PHP
Apache 配置详解(最好的APACHE配置教程)
2010/07/04 PHP
浅析application/x-www-form-urlencoded和multipart/form-data的区别
2014/06/22 PHP
php实现获取文件mime类型的方法
2015/02/11 PHP
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
php实现微信公众平台账号自定义菜单类
2015/10/11 PHP
比较详细的javascript对象的property和prototype是什么一种关系
2007/08/06 Javascript
JQuery jsonp 使用示例代码
2009/08/12 Javascript
JQuery浮动DIV提示信息并自动隐藏的代码
2010/08/29 Javascript
用nodejs访问ActiveX对象,以操作Access数据库为例。
2011/12/15 NodeJs
JavaScript关闭当前页面(窗口)不带任何提示
2014/03/26 Javascript
jquery调整表格行tr上下顺序实例讲解
2016/01/09 Javascript
jQuery与Ajax以及序列化
2016/02/01 Javascript
深入浅析JavaScript中with语句的理解
2016/05/12 Javascript
简单实现js倒计时功能
2017/02/13 Javascript
js仿微博动态栏功能
2017/02/22 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
2017/03/04 Javascript
AngularJS全局警告框实现方法示例
2017/05/18 Javascript
详解webpack-dev-server的简单使用
2018/04/02 Javascript
vue路由插件之vue-route
2019/06/13 Javascript
js实现整体缩放页面适配移动端
2020/03/31 Javascript
JS前后端实现身份证号验证代码解析
2020/07/23 Javascript
[05:06]DOTA2-DPC中国联赛 正赛 VG vs Magma选手采访
2021/03/11 DOTA
python中文编码与json中文输出问题详解
2018/08/24 Python
Python中几种属性访问的区别与用法详解
2018/10/10 Python
浅析Python3中的对象垃圾收集机制
2019/06/06 Python
如何使用Django Admin管理后台导入CSV
2020/11/06 Python
python实现KNN近邻算法
2020/12/30 Python
澳大利亚连衣裙和女装在线:Esther
2017/11/11 全球购物
Aeropostale官网:美国著名校园品牌及青少年服饰品牌
2019/03/21 全球购物
英国露营设备和户外服装购物网站:Simply Hike
2019/05/05 全球购物
伦敦香水公司:The London Perfume Company
2019/11/13 全球购物
医学专业毕业生推荐信
2014/07/12 职场文书
童年读书笔记
2015/06/26 职场文书
python基于tkinter实现gif录屏功能
2021/05/19 Python