0

我正在为以前具有 Cython 工具链的模块编写 Python 字节码优化器。虽然现在可能已弃用,但我在摆弄它时遇到了一些奇怪的事情。考虑这段简单的代码:

from opcode import opmap

globals().update(opmap)

print(STORE_GLOBAL)

这应该打印 97,正如其操作码(即 97)STORE_GLOBAL所定义的那样。opmap不过,Cython 会告诉我这STORE_GLOBAL没有定义:

Error compiling Cython file:
------------------------------------------------------------
...
from opcode import opmap

globals().update(opmap)

print(STORE_GLOBAL)
                 ^
------------------------------------------------------------

test.py:5:18: undeclared name not builtin: STORE_GLOBAL

原因很简单,我猜。我假设它不会更新全局变量,所以它不知道STORE_GLOBAL现在是一个变量。

有没有一种简单的方法来克服这个问题?

干杯

4

2 回答 2

2

原因是虽然 cython 模块有一个在 python 中公开的全局命名空间,但这个命名空间仅用于导出 python 可见变量。

但是,大多数变量对 python 是不可见的。这些变量在编译时声明并且是静态类型的。假设任何未在模块中声明的引用变量都是错误的,而是希望稍后将变量添加到模块全局变量中。

避免这种情况的唯一方法是通过模块全局引用这些变量。不是很优雅。

print(globals()["STORE_GLOBAL"])

最好的选择是通过它导入opmap和引用相关值。或者在模块中逐字写出 opmap 中的值。

于 2015-02-20T22:59:11.293 回答
0

我不知道这是否记录在任何地方,但我发现如果global在 Cython 模块的任何函数的语句中声明了一个名称,那么除了标准的 Python 含义“这个名称应该被读取和写入作为函数中的全局变量”,它还具有允许将名称作为模块中其他任何地方的全局变量读取的副作用,从而抑制了问题中的错误。

于 2017-12-23T16:17:11.730 回答