栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么对exec进行Python 3更改会破坏此代码?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么对exec进行Python 3更改会破坏此代码?

您可以使用以下命令查看每个Python版本生成的字节码:

>>> from dis import dis

并且,对于每个口译员:

#Python 3.2>>> dis(Testing.__init__)...  5          10 LOAD_GLOBAL   1 (a_func)...#Python 2.7>>> dis(Testing.__init__)...  58 LOAD_NAME     0 (a_func)...

如您所见,Python 3.2搜索名为的全局值(LOAD_GLOBAL),

a_func
而2.7首先搜索本地范围(LOAD_NAME),然后再搜索全局值。

如果在

print(locals())
之后执行操作
exec
,则会看到
a_func
__init__
函数内部创建了该代码。

我真的不知道为什么要这样做,但是似乎是对符号表处理方式的改变。

顺便说一句,如果想

a_func =None
在您的
__init__
方法之上创建一个使解释器知道它是局部变量的方法,则它将不起作用,因为字节码现在将是
LOAD_FAST
而且不会进行搜索,而是直接从列表中获取值。

我看到的唯一解决方案是将

globals()
作为第二个参数添加到
exec
,这样将创建
a_func
一个全局函数,
LOAD_GLOBAL
操作码可以访问它。

编辑

如果删除该

exec
语句,Python2.7会将字节码从更改
LOAD_NAME
LOAD_GLOBAL
。因此,使用
exec
,您的代码在Python2.x上始终会变慢,因为它必须在本地范围内搜索更改。

由于Python3

exec
不是关键字,因此解释器无法确定它是否确实在执行新代码或执行其他操作……因此字节码不会改变。

例如

>>> exec = len>>> exec([1,2,3])3

tl; dr

exec('...', globals())
如果您不在乎将结果添加到全局名称空间中,则可以解决问题



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/455803.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号