Python 在局部变量域中执行代码
问题
你想在使用范围内执行某个代码片段,并且希望在执行后所有的结果都不可见。
解决方案
为了理解这个问题,先试试一个简单场景。首先,在全局命名空间内执行一个代码片段:
>>> a = 13 >>> exec('b = a + 1') >>> print(b) 14 >>>
然后,再在一个函数中执行同样的代码:
>>> def test(): ... a = 13 ... exec('b = a + 1') ... print(b) ... >>> test() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in test NameError: global name 'b' is not defined >>>
可以看出,最后抛出了一个NameError异常,就跟在 exec()
语句从没执行过一样。 要是你想在后面的计算中使用到 exec()
执行结果的话就会有问题了。
为了修正这样的错误,你需要在调用 exec()
之前使用 locals()
函数来得到一个局部变量字典。 之后你就能从局部字典中获取修改过后的变量值了。例如:
>>> def test(): ... a = 13 ... loc = locals() ... exec('b = a + 1') ... b = loc['b'] ... print(b) ... >>> test() 14 >>>
讨论
实际上对于 exec()
的正确使用是比较难的。大多数情况下当你要考虑使用 exec()
的时候, 还有另外更好的解决方案(比如装饰器、闭包、元类等等)。
然而,如果你仍然要使用 exec() ,本节列出了一些如何正确使用它的方法。 默认情况下,exec() 会在调用者局部和全局范围内执行代码。然而,在函数里面, 传递给 exec() 的局部范围是拷贝实际局部变量组成的一个字典。 因此,如果 exec() 如果执行了修改操作,这种修改后的结果对实际局部变量值是没有影响的。 下面是另外一个演示它的例子:
>>> def test1(): ... x = 0 ... exec('x += 1') ... print(x) ... >>> test1() 0 >>>
上面代码里,当你调用 locals()
获取局部变量时,你获得的是传递给 exec()
的局部变量的一个拷贝。 通过在代码执行后审查这个字典的值,那就能获取修改后的值了。下面是一个演示例子:
>>> def test2(): ... x = 0 ... loc = locals() ... print('before:', loc) ... exec('x += 1') ... print('after:', loc) ... print('x =', x) ... >>> test2() before: {'x': 0} after: {'loc': {...}, 'x': 1} x = 0 >>>
仔细观察最后一步的输出,除非你将 loc 中被修改后的值手动赋值给x,否则x变量值是不会变的。
在使用 locals()
的时候,你需要注意操作顺序。每次它被调用的时候, locals()
会获取局部变量值中的值并覆盖字典中相应的变量。 请注意观察下下面这个试验的输出结果:
>>> def test3(): ... x = 0 ... loc = locals() ... print(loc) ... exec('x += 1') ... print(loc) ... locals() ... print(loc) ... >>> test3() {'x': 0} {'loc': {...}, 'x': 1} {'loc': {...}, 'x': 0} >>>
>>> def test3(): ... x = 0 ... loc = locals() ... print(loc) ... exec('x += 1') ... print(loc) ... locals() ... print(loc) ... >>> test3() {'x': 0} {'loc': {...}, 'x': 1} {'loc': {...}, 'x': 0} >>>
注意最后一次调用 locals()
的时候x的值是如何被覆盖掉的。
作为 locals()
的一个替代方案,你可以使用你自己的字典,并将它传递给 exec()
。例如:
>>> def test4(): ... a = 13 ... loc = { 'a' : a } ... glb = { } ... exec('b = a + 1', glb, loc) ... b = loc['b'] ... print(b) ... >>> test4() 14 >>>
大部分情况下,这种方式是使用 exec()
的最佳实践。 你只需要保证全局和局部字典在后面代码访问时已经被初始化。
还有一点,在使用 exec()
之前,你可能需要问下自己是否有其他更好的替代方案。 大多数情况下当你要考虑使用 exec()
的时候, 还有另外更好的解决方案,比如装饰器、闭包、元类,或其他一些元编程特性。
以上就是Python 在局部变量域中执行代码的详细内容,更多关于Python 局部变量域的资料请关注猪先飞其它相关文章!
相关文章
- 这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
Python astype(np.float)函数使用方法解析
这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08- 2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
- 在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
python-for x in range的用法(注意要点、细节)
这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10- 这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- 这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
- 这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
- 有一种方法,可以不打开网站而直接查看到这个网站的源代码.. 这样可以有效地防止误入恶意网站... 在浏览器地址栏输入: view-source:http://...2016-09-20
- <?php require('path.inc.php'); header('content-Type: text/html; charset=utf-8'); $borough_id = intval($_GET['id']); if(!$borough_id){ echo ' ...2016-11-25
python Matplotlib基础--如何添加文本和标注
这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 本文实例讲述了JS基于Mootools实现的个性菜单效果代码。分享给大家供大家参考,具体如下:这里演示基于Mootools做的带动画的垂直型菜单,是一个初学者写的,用来学习Mootools的使用有帮助,下载时请注意要将外部引用的mootools...2015-10-23
- 今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
- 本文实例讲述了JS+CSS实现分类动态选择及移动功能效果代码。分享给大家供大家参考,具体如下:这是一个类似选项卡功能的选择插件,与普通的TAb区别是加入了动画效果,多用于商品类网站,用作商品分类功能,不过其它网站也可以用,...2015-10-21
- 本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
- php 取除连续空格与换行代码,这些我们都用到str_replace与正则函数 第一种: $content=str_replace("n","",$content); echo $content; 第二种: $content=preg_replac...2016-11-25
- 这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
- 在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
- php简单用户登陆程序代码 这些教程很对初学者来讲是很有用的哦,这款就下面这一点点代码了哦。 <center> <p> </p> <p> </p> <form name="form1...2016-11-25