python - 如何对全局 __builtin__ 对象进行 cythonize?

标签 python python-2.7 cython cythonize

我在“cythonizing”用 python 编写的项目时遇到问题。

1. 实例化一个 python 类(在文件 myclass.py 中声明),然后在文件 main.py 中使用 setattr(__builtin__...) “声明为全局”
2. 模块(文件module.py)中声明的函数通过其全局名称(“globalclass”)访问此类实例,并设置一些值。

所以问题是:如何通过使用 setattr(__builtin__...) 在模块外部定义的“全局名称”来引用对象实例的 python 模块?

我在 Windows x86 上运行 python 2.7.15,使用 Cython 0.29.1。

当我运行纯 python 时,下面提供的代码工作正常:

python main.py


但是 cythonizing 文件 module.py 给了我一个错误:未声明的名称不是内置的引用类实例“globalclass”的全局名称。

这是文件myclass.pyx,类的定义:

class Myclass:
    def __init__(self):
        self.value = ''

    def setValue(self,text):
        self.value = text

    def printValue(self):
        print self.value


这是文件 module.pyx:这是我想要 cythonize 的文件,但 cython 说未声明的名称不是内置的“globalclass”:

def setValue():
    globalclass.setValue('test from module.py')


这是文件 main.py (入口点),其中类被实例化,并使用 setattr(__builtin__...)“声明为全局”:

import __builtin__
from myclass import Myclass
from module import setValue

if __name__ == '__main__':
    myclass = Myclass()
    setattr(__builtin__, 'globalclass', myclass)
    setValue()
    globalclass.printValue()


这是用于对所有内容进行 cythonize 的文件 setup.py:

from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension

cyextensions = [
    Extension(name='myclass', sources=['myclass.pyx']),
    Extension(name='module', sources=['module.pyx']),
    ]

setup(name='test',
      version = '0.0.1',
      description = 'test',
      packages = ['test'],
      ext_modules = cythonize(cyextensions)
)

这是我用来进行 cythonize 的命令:

python setup.py build_ext --inplace

这是我在 cythonizing 时收到的错误消息:

Error compiling Cython file:
------------------------------------------------------------
...
def setValue():
        globalclass.setValue('test from module.py')^
------------------------------------------------------------

module.pyx:2:1: undeclared name not builtin: globalclass

最佳答案

这是 Cython 与 Python 不同的地方(尽管它没有很好的文档记录)。本质上,它假设它应该能够在编译时解析所有全局名称,而您所做的事情会在运行时影响它。

Fortunately there's an option to turn this behaviour off 。只需在 setup.py 中添加两行(如上面的文档所示)

from Cython.Compiler import Options
Options.error_on_unknown_names = False

关于python - 如何对全局 __builtin__ 对象进行 cythonize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58236075/

相关文章:

在远程/虚拟机上运行的Python脚本

python-2.7 - 嵌入 SSL 证书

python - Numpy:跨越多 channel 图像

Python - 函数中的默认参数

python - 在 Python 脚本中运行 Julia 文件

python - 使用 fetchone()[0] 时,"TypeError: ' NoneType ' object is unsubscriptable"

python - 使用 win32com 模块的 Python 2.7 中的 Qualcomm QPST 自动化服务器

python - 如何在 cython 中使用 gsl

python - Reddit安装 "Cannot find Cython. Skipping Cython build."

python - 欧拉计划 #25 : Keep getting Overflow error (result to large) - is it to do with calculating fibonacci number?