我正在写一个python类,我想使用cython早期打字来加速执行.当我尝试cython编译以下内容时
出现错误"Syntax error in C variable declaration":
import numpy as np
cimport numpy as np
class MyClass:
def __init__( self, np.ndarray[double, ndim=1] Redges ):
self.Redges = Redges
cdef double self.var1
Run Code Online (Sandbox Code Playgroud)
该错误涉及最后一行涉及的语法self.var1.我不允许直接输入类属性吗?我是否总是要将其分解为两个步骤,例如:
cdef double var1
self.var1 = var1
Run Code Online (Sandbox Code Playgroud)
完整的错误回溯是,
test.pyx:7:24:
Syntax error in C variable declaration
Traceback (most recent call last):
File "setup.py", line 9, in <module>
ext_modules = cythonize('test.pyx'), # accepts a glob pattern
File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 713, in cythonize
cythonize_one(*args[1:])
File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 780, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: calc_iliev_sphere.pyx
Run Code Online (Sandbox Code Playgroud)
Bak*_*riu 11
你想要的是定义一个扩展类型.特别是您的代码应如下所示:
import numpy as np
cimport numpy as np
cdef class MyClass:
cdef double var1
cdef np.ndarray[double, ndim=1] Redges
def __init__( self, np.ndarray[double, ndim=1] Redges ):
self.Redges = Redges
Run Code Online (Sandbox Code Playgroud)
请注意,您不能在正常情况下强加实例属性的类型class,因为python允许人们更改它们及其类型.如果你试图cdef在普通的python类中放置一个类级别,你将收到Cython的编译器错误.
编译上面的代码会引发以下错误:
Error compiling Cython file:
------------------------------------------------------------
...
import numpy as np
cimport numpy as np
cdef class MyClass:
cdef double var1
cdef np.ndarray[double, ndim=1] Redges
^
------------------------------------------------------------
test_cython.pyx:6:36: Buffer types only allowed as function local variables
Run Code Online (Sandbox Code Playgroud)
现在,这不是语法错误.语法很好.问题是你根本不能拥有np.ndarray类型的实例属性.这是cython的一个限制.实际上,如果您对该cdef np.ndarray[double, ndim=1] Redges行进行注释,则文件编译正确:
码:
import numpy as np
cimport numpy as np
cdef class MyClass:
cdef double var1
#cdef np.ndarray[double, ndim=1] Redges
def __init__( self, np.ndarray[double, ndim=1] Redges ):
self.Redges = Redges
Run Code Online (Sandbox Code Playgroud)
输出:
$cython test_cython.pyx
$
Run Code Online (Sandbox Code Playgroud)
注意:没有输出cython意味着文件已成功编译.
我在上面链接的文档中解释了这个限制,参见属性:
扩展类型的属性直接存储在对象的C中
struct.[omissis]注意:您只能为Python访问公开简单的C类型,例如整数,浮点数和字符串.您还可以公开Python值属性.
您只能公开简单 C数据类型的事实是因为属性是struct.允许像这样的缓冲区np.ndarray需要具有可变大小structs.
如果你想要一个类型np.ndarray最好的实例属性,你可以做的是定义一个泛型类型的属性,object并为其分配数组:
import numpy as np
cimport numpy as np
cdef class MyClass:
cdef double var1
cdef object Redges
def __init__( self, np.ndarray[double, ndim=1] Redges ):
self.Redges = Redges
Run Code Online (Sandbox Code Playgroud)
但是现在每次访问时self.Redges都会失去cython的速度.如果多次访问它,可以将其分配给具有正确类型的局部变量.这就是我的意思:
import numpy as np
cimport numpy as np
cdef class MyClass:
cdef double var1
cdef object Redges
def __init__( self, np.ndarray[double, ndim=1] Redges ):
self.Redges = Redges
def do_stuff(self):
cdef np.ndarray[double, ndim=1] ar
ar = self.Redges
ar[0] += 1
return ar[0]
Run Code Online (Sandbox Code Playgroud)
通过这种方式,do_stuff你可以在函数内部使用cython的所有速度ar.