Это в основном о наследовании. Предположим, я наследую от вашего класса 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
Как __init__
в конечном итоге вызывается, полностью зависит от классов, которые от него наследуются. Помните, что может быть несколько уровней наследования. :
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)
т.е. NamedHelloPlus1
контролирует, какие аргументы получает NamedValue
. С __cinit__
Cython все вызовы __cinit__
получают точно такие же аргументы (потому что Cython организует вызов - вы не можете вызвать его вручную).