如何 cythonize 全局 __builtin__ 对象?
How to cythonize global __builtin__ objects?
我有一个问题"cythonizing"一个用python写的项目。
1.实例化一个pythonclass(在文件myclass.py中声明),然后"declared global"使用setattr(__builtin__ ...) 在文件 main.py
中
2. 在模块(文件module.py)中声明的函数通过其全局名称("globalclass")访问此class实例,并设置一些值.
所以问题是:如何通过 setattr(__builtin__...) 在模块外部定义的 "global name" 来引用对象实例的 python 模块?
I 运行 python 2.7.15 on windows x86,Cython 0.29.1.
当我 运行 pure python:
时,下面提供的代码工作正常
python main.py
但是 cythonizing 文件 module.py 给我一个错误: undeclared name not builtin reference the global name of the class instance "globalclass".
这里是文件myclass.pyx,class的定义:
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(入口点),其中 class 被实例化,"declared global" 使用 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
cython 编译器在运行时获取有关 python 内置函数的信息。
所以在编译之前/编译时修改'builtins'将解决问题而不需要采取进一步的行动。
即使用 sitecustomize、usercustomize 或一些 'yourname'.pth 来
'import my_builtin_patching_module' 用于编译步骤。
确保导入将采用您的原始 .py,而不是编译后的文件,
否则导入的 .pyd/.so 可能会被锁定,从而阻止编译器输出。
我有一个问题"cythonizing"一个用python写的项目。
1.实例化一个pythonclass(在文件myclass.py中声明),然后"declared global"使用setattr(__builtin__ ...) 在文件 main.py
中
2. 在模块(文件module.py)中声明的函数通过其全局名称("globalclass")访问此class实例,并设置一些值.
所以问题是:如何通过 setattr(__builtin__...) 在模块外部定义的 "global name" 来引用对象实例的 python 模块?
I 运行 python 2.7.15 on windows x86,Cython 0.29.1.
当我 运行 pure python:
python main.py
但是 cythonizing 文件 module.py 给我一个错误: undeclared name not builtin reference the global name of the class instance "globalclass".
这里是文件myclass.pyx,class的定义:
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(入口点),其中 class 被实例化,"declared global" 使用 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
cython 编译器在运行时获取有关 python 内置函数的信息。
所以在编译之前/编译时修改'builtins'将解决问题而不需要采取进一步的行动。
即使用 sitecustomize、usercustomize 或一些 'yourname'.pth 来
'import my_builtin_patching_module' 用于编译步骤。
确保导入将采用您的原始 .py,而不是编译后的文件,
否则导入的 .pyd/.so 可能会被锁定,从而阻止编译器输出。