Skip to main content
 首页 » 编程设计

python之如何 cythonize 全局 __builtin__ 对象

2024年08月13日34shihaiming

我在“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