Cython:使用 globals().update(...)?

Cython: use globals().update(...)?

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

from opcode import opmap

globals().update(opmap)

print(STORE_GLOBAL)

这应该打印 97,因为 STORE_GLOBALopmap 中定义了它的操作码(即 97)。不过,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 现在是一个变量。

有什么简单的方法可以解决这个问题吗?

干杯

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

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

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

print(globals()["STORE_GLOBAL"])

最好的替代方法是导入 opmap 并通过它引用相关值。或者在你的模块中逐字写出 opmap 中的值。

我不知道这是否在任何地方记录,但我发现如果在 Cython 模块的任何函数的 global 语句中声明了名称,那么除了标准 Python "this name should be read and written as a global variable in this function" 的含义,它还有一个副作用,即允许名称在模块的其他任何地方被 读取 作为全局变量,从而抑制错误问题。