2016-11-07 4 views
2

Я озадачен со следующей ошибкой в ​​питоне 2.7.12 Пусть у нас есть определение класса внутри класса, что-то похожего на это:Использования супер внутри вложенного класс

class C(object): 
    def __init__(self): 
     print "class C" 


class D(object): 
    def __init__(self): 
     print "class D" 


class A(D): 

    class B(C): 
     def __init__(self): 
      # Strangely here B is "not defined", why? 
      super(B, self).__init__() 
      print "class B" 

    def __init__(self): 
     super(D, self).__init__() 
     print "class A" 

    def do_something(self): 
     b_class = self.B() 
     print "b_class within A : {}".format(b_class) 


a_class = A() 
a_class.do_something() 

но если мы выделим определение класса B за пределами класса A, все работает хорошо.

Нужно ли использовать «супер» по-разному при вызове внутри вложенного класса? Я не понимаю, почему его использование будет отличаться внутри или вне вложенного класса. Любые указатели?

+2

* Есть указатели * Там нет указателей на Python;) – Leon

ответ

7

Проблема не в подклассе или суперклассе, а в гнездовании. B сам не определено, только A.B есть.

Обратите внимание, что в Python практически нет веской причины для гнездования классов.

+0

Действительно это так, хотя я бы подумал, что супер неявно? учитывал контекст ... – TocToc

4

Вам нужно обратиться B своим полным именем, A.B:

class C(object): 
    def __init__(self): 
     print "class C" 


class D(object): 
    def __init__(self): 
     print "class D" 


class A(D): 

    class B(C): 
     def __init__(self): 
      super(A.B, self).__init__() 
      print "class B" 

    def __init__(self): 
     super(D, self).__init__() 
     print "class A" 

    def do_something(self): 
     b_class = self.B() 
     print "b_class within A : {}".format(b_class) 


>>> a_class = A() 
>>> a_class.do_something() 

class A 
class C 
class B 
b_class within A : <__main__.B object at 0x7f0cac98cbd0> 
+0

Интересно, почему «класс D» отсутствует на выходе. – Leon

+2

@Leon это потому, что 'A .__ init__' вызывает' super (D, self) .__ init __() ', что означает« вызывает «__init__» D-суперкласса »(в данном случае' object .__ init__'). Если вы хотите вызывать 'D .__ init__' из' A .__ init__', вы должны использовать 'super (A, self) .__ init __()' вместо;) –

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