2015-09-28 4 views
8

У меня есть класс иерархии < - B < - C, в B, мне нужна некоторая обработка в конструкторе, так что я придумал этот код с этого поста: Understanding Python super() with __init__() methodsОшибка максимальной глубины рекурсии в Python при вызове супер-init.

#!/usr/bin/python 

class A(object): 
    def __init__(self, v, v2): 
     self.v = v 
     self.v2 = v2 

class B(A): 
    def __init__(self, v, v2): 
     # Do some processing 
     super(self.__class__, self).__init__(v, v2) 

class C(B): 
    def hello(): 
     print v, v2 


b = B(3, 5) 
print b.v 
print b.v2 

c = C(1,2) 
print c 

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

File "evenmore.py", line 12, in __init__ 
    super(self.__class__, self).__init__(v, v2) 
RuntimeError: maximum recursion depth exceeded while calling a Python object 

Что может быть неправильным?

+0

'супер (B, self)'. – ekhumoro

+0

Или если вы можете использовать Python 3, просто 'super()' (Python 3 автоматически заполняет аргументы). – ShadowRanger

ответ

6

Первое, что нужно учитывать: C наследует конструктор из B (потому что он не определен в C).

Вторая вещь, чтобы рассмотреть: self.__class__ в __init__ вызов в классе C является C, а не B.

Давайте проанализируем:

  • C().__init__ вызовы super(self.__class__, self).__init__(v, v2) который разрешен к super(C, self).__init__(v, v2), что означает B.__init__(self, v, v2).
  • Первый аргумент, переданный B.__init__, имеет тип C. super(self.__class__, self).__init__(v, v2) снова разрешен до B.__init__(self, v, v2).
  • И снова, и снова, и снова. И есть бесконечная рекурсия.
1

Предоставление первого параметра супер, поскольку имя класса решает эту проблему.

+0

Должно быть понятно, почему; 'self .__ class__' всегда является конкретным классом, а не именем любого класса, в котором вы находитесь в MRO. На самом деле, второй ответ в сообщении, на который вы ссылаетесь, подробно рассматривается в этом вопросе. –

Смежные вопросы