Cython использование cinit () - PullRequest
       2

Cython использование cinit ()

7 голосов
/ 06 октября 2011

У меня есть:

      cdef class BaseClass():
           def __cinit__(self,char* name):
               print "BaseClass __cinit__()"
               #...
           def __dealloc__():
               print "BaseClass __dealloc__()"
               #...
      cdef class DerClass(BaseClass):
           def __cinit__(self,char* name,int n):
               print "DerClass __cinit__()"
               #...
           def __dealloc__():
               print "DerClass __dealloc__()"
               #...

, когда я вызываю DerClass в cyhton, случается, что конструктор BaseClass вызывается автоматически, то, что он должен напечатать:

       BaseClass __cinit__()
       DerClass __cinit__()
       DerClass __dealloc__()
       BaseClass __dealloc__()

, ноэто не так, это сбой те, которые я называю DerClass ('Ciao').почему так происходит и как я могу избежать вызова cinit BaseClass.Спасибо!

Ответы [ 2 ]

4 голосов
/ 11 декабря 2012

Ну, вы правы, что должны увидеть метод cinit , вызываемый в вашем родительском классе.Это так прямо здесь, в документах.

http://docs.cython.org/src/userguide/special_methods.html

Вот то, что я пытался использовать:

cdef class BaseClass:
   def __cinit__(self,char* name):
       print "BaseClass __cinit__()"
       #...
   def __dealloc__(self):
       print "BaseClass __dealloc__()"
       #...
cdef class DerClass(BaseClass):
   def __cinit__(self,char* name,int n):
       print "DerClass __cinit__()"
       #...
   def __dealloc__(self):
       print "DerClass __dealloc__()"
       #...

Он скомпилирован, но выдает мне эту ошибку, когда япопытался запустить его:

mike@computer:~/testing$ python runner.py 
DerClass __dealloc__()
BaseClass __dealloc__()
Traceback (most recent call last):
  File "runner.py", line 4, in <module>
    DerClass('Ciao', 1)
  File "test.pyx", line 2, in test.BaseClass.__cinit__ (test.c:488)
    def __cinit__(self,char* name):
TypeError: __cinit__() takes exactly 1 positional argument (2 given)
mike@computer:~/testing$

Поэтому я изменил BaseClass. cinit , чтобы он также принял параметр int n, который DerClass. cinit делает:

cdef class BaseClass:
   def __cinit__(self, char * name, int n):
       print "BaseClass __cinit__()"
       #...
   def __dealloc__(self):
       print "BaseClass __dealloc__()"
       #...
cdef class DerClass(BaseClass):
   def __cinit__(self,char* name,int n):
       print "DerClass __cinit__()"
       #...
   def __dealloc__(self):
       print "DerClass __dealloc__()"
       #...

И теперь, похоже, все работает нормально:

mike@computer:~/testing$ python runner.py 
BaseClass __cinit__()
DerClass __cinit__()
DerClass __dealloc__()
BaseClass __dealloc__()
mike@computer:~/testing$ 

Вот мой файл runner.py:

from test import *
if __name__ == "__main__":
    DerClass('Ciao', 1)
3 голосов
/ 13 октября 2015

Приведенный выше ответ может быть не самым лучшим решением.Чтение раздела «Методы инициализации: __cinit __ () и __init __ ()» приведенной выше ссылки дает следующую информацию:

Если тип расширения имеет базовый тип, метод __cinit__() базового типавызывается автоматически перед вызовом вашего __cinit__() метода;Вы не можете явно вызвать унаследованный метод __cinit__().

и

Если вы ожидаете подклассы вашего типа расширения в Python, вы можете найти полезным дать __cinit__() Метод * и ** аргументы, чтобы он мог принимать и игнорировать дополнительные аргументы.

Таким образом, мое решение состояло бы в том, чтобы просто заменить аргументы __cinit()__ в BaseClass, чтобы переменное число аргументов могло быть передано любому производному классу:

cdef class BaseClass:
    def __cinit__(self, *argv): 
        print "BaseClass __cinit__()"
        #...
def __dealloc__(self):
        print "BaseClass __dealloc__()"
        #...

cdef class DerClass(BaseClass):
    def __cinit__(self,char* name, int n):
        print "DerClass __cinit__()"
        #...
    def __dealloc__(self):
        print "DerClass __dealloc__()"
        #...

См. здесь для объяснения переменной *args в python

...