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

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

为什么对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())
如果您不在乎将结果添加到全局名称空间中,则可以解决问题



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5431329.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-11
下一篇2022-12-11

发表评论

登录后才能评论

评论列表(0条)

    保存