2016-07-29 34 views
-3

According to the docs,Python __new__ - muss eine Instanz von cls zurückkehren

Typische Implementierungen eine neue Instanz der Klasse erstellen, indem der __new__() Methode der übergeordneten Klasse super(currentclass, cls).__new__(cls[, ...]) mit entsprechenden Argumenten aufgerufen wird und dann Modifizierung der neu geschaffenen Instanz als notwendig, bevor Sie es zurückgeben.
...

Wenn __new__ eine Instanz von cls nicht zurückkehrt, dann wird die neue __init__() Methode der Instanz nicht geltend gemacht werden.

Die simplest implementation of __new__:

class MyClass: 
    def __new__(cls): 
     RetVal = super(currentclass, cls).__new__(cls) 
     return RetVal 

Wie genau funktioniert super(currentclass, cls).__new__(cls[, ...])cls ein Objekt vom Typ zurückgeben?

Diese Anweisung ruft object.__new__(cls) auf, wobei clsMyClass ist.

Also wie Klasse object wissen, wie man den Typ MyClass erstellen?

+1

Sie * erzählten *, welcher Typ das zurückgegebene Objekt haben sollte. Dafür ist der Parameter 'cls' gedacht. – user2357112

+0

@ user2357112 Ich bekomme Ihre Antwort nicht. Der Rückgabetyp, den es erwartet, ist "cls". Wie wird 'super (aktuelle Klasse, cls) .__ neue __ (cls)' eine 'cls' zurückgegeben? Sagst du, dass es implizit wirkt? – Adrian

+1

'object .__ new__' schaut auf den 'cls'-Parameter, an den Sie ihn übergeben haben, und sagt:" Mensch, ich denke Adrian will ein Objekt vom Typ 'cls'. Ich sollte eins davon machen." – user2357112

Antwort

0

Nur wenige Dinge, vor allem explizite Vererbung von object so schreiben müssen:

class MyClass(object): 

Sie sollten über old classes and new classes auf Python (nur auf Python 2, in Python 3 spielt es keine Rolle) lesen

Für Ihre Frage, ich denke, Sie haben den Punkt oder die Syntax von super() Funktionen verpasst. Auch kleine Änderung an Ihrem Code: durch super(MyClass, cls) mit

RetVal = super(MyClass, cls).__new__(cls) 

Auf diese Weise können Sie auf die Eltern-Klasse verweisen und ein Verfahren dieser Eltern-Klasse neue (natürlich können Sie eine andere Methode verwenden) Aufruf

bearbeiten nach der Lektüre Ihrer Kommentare, werde ich nur hinzufügen, dass super() nicht 3 Argumente in Python zu nehmen hat, so vielleicht ist es für Sie mehr trivial ist. Sehr zu empfehlen, mehr über die super()here

+0

Ich verstehe die beabsichtigten Effekte. Ich verstehe nicht, was "cls" zu "super" ** neben "MyClass" macht. – Adrian

+0

Ich weiß, dass 'issubclass (class2, class1)' muss wahr sein, aber warum braucht 'super'' cls', was auch immer es zurückgibt? – Adrian

+0

Das ist eine Frage über 'super()', nicht über '__new __()'. –

1

super(MyClass, cls).__new__(cls) sucht zuerst die MRO (Methode Auflösung Reihenfolge) des cls Objekts zu lesen (das Überspringen Vergangenheit MyClass in dieser Reihenfolge), bis es ein Objekt mit einem __new__ Attribute findet.

In Ihrem Fall, das heißt object.__new__:

>>> class MyClass: 
...  def __new__(cls): 
...   RetVal = super(MyClass, cls).__new__(cls) 
...   return RetVal 
... 
>>> MyClass.__mro__ 
(<class '__main__.MyClass'>, <class 'object'>) 
>>> hasattr(MyClass.__mro__[1], '__new__') 
True 

aber wenn Sie MyClass und gemischt in einer anderen Klasse in den MRO mit einem __new__ Methode subclassed es dann könnte eine andere Methode.

object.__new__ ist in C implementiert, siehe object_new() function; Es enthält einen Hook für abstrakte Basisklassen, um sicherzustellen, dass Sie nicht versuchen, eine abstrakte Klasse zu instanziieren, und delegiert dann an den tp_alloc-Slot, der normalerweise auf PyType_GenericAlloc gesetzt wird, der dem Heap eine neue PyObject-Struktur hinzufügt. Es ist diese Struktur, die die Instanz für den Interpreter darstellt.

+0

Sollte 'currentclass' nicht durch' MyClass' ersetzt werden? – Adrian

+1

@Adrian: Ich folgte Ihrem Beispiel in Ihrer Frage. Ja, ein korrekter Aufruf würde 'MyClass' verwenden. –

+0

Ok. Also können Sie dann auf ** Dokumentation ** zeigen, die erklärt, was 'super (MyClass, cls)' ** bedeutet ** d. H. Wie "super" auf seine zwei Argumente reagiert, um zurückzukehren. . . was auch immer es zurückgibt. [Python.org] (https://docs.python.org/3/library/functions.html#super) gibt diese Information NICHT an. – Adrian