cython - 如何在 Cython 中使用 atexit?
问题描述
我正在尝试在 cython 中制作以下代码进行编译
from cython_gsl cimport *
import atexit
cdef gsl_rng_type * rng_T = gsl_rng_default
cdef gsl_rng * rng_r
gsl_rng_env_setup()
rng_r = gsl_rng_alloc(rng_T)
@atexit.register
def free_gsl_rng():
gsl_rng_free(rng_r)
但我总是得到错误
分配给非左值 'atexit'
对应的 .pxd 文件
from cython_gsl cimport *
cdef gsl_rng * rng_r
我实际上是用 SageMath 8.7 编译的
sage setup.py build_ext --inplace
这是我的 setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import cython_gsl
extensions = [
Extension("gsl_rand", ["gsl_rand.pyx"],
libraries=cython_gsl.get_libraries(),
library_dirs=[cython_gsl.get_library_dir()],
include_dirs=[cython_gsl.get_cython_include_dir()]
),
]
setup(
name='Simulation of k-cut on conditional Galton-Watson trees',
cmdclass={'build_ext': build_ext},
include_dirs = [cython_gsl.get_include()],
ext_modules=cythonize(extensions),
)
Full error log here
sage setup.py build_ext --inplace
Compiling gsl_rand.pyx because it changed.
[1/1] Cythonizing gsl_rand.pyx
/home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/Cython/Compiler/Main.py:367: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /home/xing/Dropbox/Research/2017/k-cut/GW/sage/moments/cython-v5/gsl_rand.pxd
tree = Parsing.p_module(s, pxd, full_module_name)
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:65:9: 'GSL_EMAXITER' redeclared
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:67:9: 'GSL_EROUND' redeclared
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:69:9: 'GSL_ESING' redeclared
warning: /home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/cython_gsl/gsl_integration.pxd:71:9: 'GSL_EDIVERGE' redeclared
warning: gsl_rand.pyx:14:0: Overriding cdef method with def method.
Error compiling Cython file:
------------------------------------------------------------
...
# cython: profile=False
from cython_gsl cimport *
import atexit
^
------------------------------------------------------------
gsl_rand.pyx:5:7: Assignment to non-lvalue 'atexit'
Error compiling Cython file:
------------------------------------------------------------
...
cdef gsl_rng * rng_r
gsl_rng_env_setup()
rng_r = gsl_rng_alloc(rng_T)
@atexit.register
^
------------------------------------------------------------
gsl_rand.pyx:13:0: Object of type 'int (void (*)(void) nogil) nogil' has no attribute 'register'
Traceback (most recent call last):
File "setup.py", line 29, in <module>
ext_modules=cythonize(extensions),
File "/home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 1097, in cythonize
cythonize_one(*args)
File "/home/xing/Downloads/software/sage/8.7/local/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 1220, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: gsl_rand.pyx
解决方案
atexit
正在 cimported from cython_gsl cimport *
。这似乎发生在 line 上from libc.stdlib cimport *
。因此,此名称与 Pythonatexit
模块冲突。我认为这是一个很好的例子,说明为什么from something [c]import *
不推荐,无论是在您的代码中还是在 cython_gsl 的代码中。由于 Cython 有两种类型的名称(用于 Python 和 C),因此它会变得更加混乱,因此您会收到奇怪的错误消息。
最好的解决方案是执行cimport cython_gsl
或导入您需要的特定符号:from cython_gsl cimport gsl_rng, etc
. 请记住同时更改 pyx 和 pxd 文件。
更糟糕的解决方法是atexit
在导入模块时重命名它:import atexit as ae
.
推荐阅读
- scala - 如何在 Haskell 中创建 ADT?
- android - 动态降低recyclerview itemview高度,使itemview布局重叠
- jsf - 部署时 com.sun.enterprise.deployment.util.ComponentValidator.accept() 处的 java.lang.NullPointerException
- linux - 由“setitimer()”启动的计时器会重新启动吗?
- python-3.x - 如何选择一堆行
- node.js - 安装 npm 模块构建失败(来自 ./node_modules/babel-loader/lib/index.js)后,更改为新的 repo 无法启动我的服务器:
- python - 如何将 dtype(uint16) 数据转换为 16 位 png 图像?
- c# - C# Web Api:如何获取唯一的用户设备 ID?
- ruby-on-rails - Rails:即使我的迁移创建了表,为什么我的模型为零?
- python - 如何循环通过python中的有效负载将数据发送到服务器