您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

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

为什么对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__)
...
  5           8 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_NAMELOAD_GLOBAL。因此,使用exec,您的代码在Python2.x上始终会变慢,因为它必须在本地范围内搜索更改。

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

例如

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

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

python 2022/1/1 18:35:31 有229人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶