Cython:使用 globals().update(...)?
Cython: use globals().update(...)?
我正在为以前具有 Cython 工具链的模块编写 Python 字节码优化器。虽然现在可能已被弃用,但我在摆弄它时遇到了一些奇怪的事情。考虑这段简单的代码:
from opcode import opmap
globals().update(opmap)
print(STORE_GLOBAL)
这应该打印 97,因为 STORE_GLOBAL
在 opmap
中定义了它的操作码(即 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" 的含义,它还有一个副作用,即允许名称在模块的其他任何地方被 读取 作为全局变量,从而抑制错误问题。
我正在为以前具有 Cython 工具链的模块编写 Python 字节码优化器。虽然现在可能已被弃用,但我在摆弄它时遇到了一些奇怪的事情。考虑这段简单的代码:
from opcode import opmap
globals().update(opmap)
print(STORE_GLOBAL)
这应该打印 97,因为 STORE_GLOBAL
在 opmap
中定义了它的操作码(即 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" 的含义,它还有一个副作用,即允许名称在模块的其他任何地方被 读取 作为全局变量,从而抑制错误问题。