【问题标题】:Cython: use globals().update(...)?Cython:使用 globals().update(...)?
【发布时间】:2015-02-20 22:05:48
【问题描述】:

我正在为以前具有 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 现在是一个变量。

有没有简单的方法来解决这个问题?

干杯

【问题讨论】:

    标签: python cython opcodes


    【解决方案1】:

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

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

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

    print(globals()["STORE_GLOBAL"])
    

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

    【讨论】:

    • 是的,我也是这么想的。感谢您的澄清。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2018-09-19
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-29
      相关资源
      最近更新 更多