
您可以使用以下命令查看每个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()) 如果您不在乎将结果添加到全局名称空间中,则可以解决问题欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)