我在“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 给我一个错误:undeclared name not builtin reference the global name of the class instance "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:这是我想用 cython 化的文件,但是 cython 说 undeclared name not builtin "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 all 的文件 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
