2017-04-21 1 views
0

am folgenden Beispiel Werfen Sie einen BlickEine Verwirrung auf Typ .__ init__ in Python 2

class Base(type): 
    def __init__(cls, name, bases, dict_): 
     print 'Base.__init__() with cls %s, name %s...' % (cls, name,) 
     type.__init__(cls, name, bases, dict_) 

M = Base('M', (object,), {}) 

class D1(Base): 
    pass 

class D2(M): 
    pass 

Der Ausgang ist

Base.__init__() with cls <class '__main__.M'>, name M... 
Base.__init__() with cls <class '__main__.D2'>, name D2... 

ich über das Ergebnis so verwirrt fühlen,

  1. Warum Base.__init__ für D2 aufgerufen werden, auch haben wir keine Instanz von D2 erstellen?
  2. Da Base.__init__ für D2 aufgerufen werden, warum D1 nicht?
+0

Err ... 'Base (Argumente)' 'ruft Basis .__ init__' ... – ForceBru

+1

„Warum 'Basis .__ init__' wird für 'D2' aufgerufen, auch wenn wir keine Instanz von' D2' erstellt haben? " - weil Sie eine Instanz von "Base" erstellt haben. Diese Instanz ist "D2". – user2357112

Antwort

2

Base.__init__ ist das erste Mal, wenn Sie das tun genannt:

M = Base('M', (object,), {}) 

Sie eine Instanz von Base zu schaffen, so dass ihre __init__ Methode, nichts überraschend aufgerufen wird.

Es ist das zweite Mal bei der Erstellung D2 weil die Schaffung einer Klasse ruft die Methode des __init__Metaklasse (ja, Klasse der Klasse), die Base genannt wird; D2 ist eine Instanz von Base.

Es ist nicht für D1 seit D1 ist ein Subtyp/Unterklasse von Base und nicht eine Instanz davon genannt wird.

Hinweis, was passiert, wenn Sie Base die Metaklasse von D1 statt ihrer Oberklasse machen:

class D1(object): 
    __metaclass__ = Base 
    pass 

# Base.__init__() with cls <class 'D1'>, name D1... 
+0

Ich weiß nicht, wie 'metaclass' funktioniert. So bin ich immer noch verwirrt, warum 'Base .__ init__' aufgerufen wird, wenn D2 eine Instanz von' Base' ist; auch nach dem Lesen http://StackOverflow.com/Questions/100003/what-is-a-metaclass-in-python, weil '__metaclass__' hier nicht verwendet wird. – Jacky

+0

Ein anderes Problem: Ist die Position von "__metaclass__" wichtig? – Jacky

+0

[Das Grundprinzip der __metaclass__] (http://jfine-python-classes.readthedocs.io/en/latest/metaclass-attribute.html#the-basic-principle-of-the-metaclass) –