为什么 cpdef 不与 cython 中的 __init__ 一起使用

uda*_*day 6 cython

在阅读有关类的 Cython 文档后有一个基本问题,但我想弄清楚。以下是Cython 文档中的示例代码:

cdef class Rectangle:
    cdef int x0, y0
    cdef int x1, y1
    def __init__(self, int x0, int y0, int x1, int y1):
        self.x0 = x0; self.y0 = y0; self.x1 = x1; self.y1 = y1
    cpdef int area(self):
        cdef int area
        area = (self.x1 - self.x0) * (self.y1 - self.y0)
        if area < 0:
            area = -area
        return area
Run Code Online (Sandbox Code Playgroud)

为什么__init__前面是defand 而不是cdefor cpdef

我意识到有一个__cinit__函数,但是不应该cpdef __init__使__init__代码更快吗?

或者,我们是否应该将需要运行得非常快的代码放在该__cinit__部分中,而将我们可以运行得较慢的代码放在该__init__部分中?

Dav*_*idW 1

cpdef不影响函数内代码的速度。它仅创建一个可以直接从 C/Cython 调用的函数版本(无需通过 Python 调用机制)。函数的“内部”在这两种情况下都会进行编译,并以完全相同的速度运行。有关完整讨论,请参阅cython 中 def、cdef 和 cpdef 的定义。

大多数 Cython 特殊函数(名称为 形式的函数__xxx__)仅限于定义为def函数。本质上是因为它们对 Python 解释器有特殊用途,而 Cython 将无法使用 C 快捷方式版本。__init__也不例外 - 它是正常 Python 构造机制的一部分,因此只有将其作为 Python 方法调用才有意义。

__cinit__是一个稍微奇怪的情况 - 它只能由 Cython 调用(隐式),而不能由用户调用。因此,它实际上并不是一个普通的def,cdefcpdef方法。因此,这只是语言设计的问题,使用什么关键字来定义它(无论您选择什么,它总是以相同的方式调用)。就它接受的参数而言,它的行为就像一个def函数,因为它可以处理*args并且**kwds只能从Python对象直接转换的类型(即不是C指针)。


如果您可以创建一个直接从 Cython 调用的备用cdef(或cpdefstaticmethod构造函数,则可以。文档中对此进行了讨论