主要是关于继承。假设我继承了你的类C
:
class D(C):
def __init__(self):
pass # oops forgot to call C.__init__
class E(C):
def __init__(self):
super().__init__(self)
super().__init__(self) # called it twice
How __init__
最终被调用完全取决于继承它的类。请记住,可能存在多层继承。
此外,创建包装 C/C++ 对象的类的一个相当常见的模式是创建staticmethod cdef作为替代构造函数的函数 https://cython.readthedocs.io/en/latest/src/userguide/extension_types.html#existing-pointers-instantiation:
cdef class C:
def __cinit__(self):
print("In __cinit__")
@staticmethod
cdef make_from_ptr(void* x):
val = C.__new__(C)
# do something with pointer
return val
再次在这种情况下,__init__
通常不被调用。
相比之下__cinit__
保证被调用一次,并且这由 Cython 在过程的早期阶段自动发生。当您有以下情况时,这是最重要的cdef
您的类在初始化时所依赖的属性(例如 C 指针)。 Python 派生类甚至不可能设置这些,但是__cinit__
可以确保他们是。
就您而言,这可能并不重要 - 使用您满意的任何一个。
就“修改后的参数”而言,它是说你不能用__cinit__
:
class NameValue:
def __init__(self, name, value):
self.name = name
self.value = value
class NamedHelloPlus1(NamedValue):
def __init__(self, value):
super().__init__("Hello", value+1)
i.e. NamedHelloPlus1
控制什么参数NamedValue
得到。和__cinit__
Cython 所有调用__cinit__
接收完全相同的参数(因为 Cython 安排调用 - 您无法手动调用它)。