Implementierung von NoneType, Reasons und Details

8

Ich habe kürzlich irgendwo gelesen, dass der spezielle Wert None in Python ein Singleton-Objekt seiner eigenen Klasse ist, speziell NoneType . Dies erklärt eine Menge, da die meisten Fehler, die None in Python betreffen, AttributeError s statt eines speziellen "NoneError" oder etwas erzeugen.

Da all diese AttributeErrors die Attribute widerspiegelten, die NoneType fehlten, war ich fasziniert von den Attributen, die NoneType hat , falls vorhanden.

Ich habe mich entschieden, in diese NoneType zu schauen und mehr darüber zu erfahren. Ich habe immer den besten Weg gefunden, etwas über ein neues Sprachfeature zu lernen, es zu benutzen, also habe ich versucht, NoneType in IDLE zu instanziieren:

%Vor%

Dies führte zu einem Fehler:

%Vor%

Verwirrt habe ich None inspiziert, um zu sehen, ob ich den korrekten Typnamen bekommen habe. Sicher genug,

%Vor%

Nun sehr verwirrt, habe ich eine schnelle Google-Suche gemacht. Dies enthüllte, dass aus irgendeinem Grund NoneType irgendwie in Python 3 entfernt wurde.

Nun, ich, ha ha! Ich kann das umgehen, indem ich den Typ von None in einer Variablen speichere, da Klassen Objekte in Python sind. Dies schien arbeiten:

%Vor%

Und als ich n druckte, bekam ich ziemlich genau das, was ich erwartet hatte:

%Vor%

Aber dann ist das passiert:

%Vor%

Und:

%Vor%

Meine Variable n IS None . Nicht nur der gleiche Typ wie None . Es ist None . Das habe ich nicht erwartet.

Ich habe versucht, mit dis mehr Informationen über NoneType zu erhalten, aber als ich

anrief %Vor%

Es hat keine Ausgabe erzeugt.

Ich habe dann versucht, die Methode __new__ zu untersuchen, die mehrere Benutzer in den Kommentaren erwähnt haben:

%Vor%

Weitere Fehler.

Hier sind meine Fragen:

  • Warum ist n genau dasselbe Objekt wie None ?
  • Warum wurde die Sprache so entworfen, dass n genau dasselbe Objekt ist wie None ?
  • Wie würde man dieses Verhalten in Python überhaupt umsetzen?
ApproachingDarknessFish 30.12.2013, 03:52
quelle

4 Antworten

1

Warum ist n genau dasselbe Objekt wie None ?

Die C-Implementierung behält eine Singleton-Instanz bei. NoneType.__new__ gibt die Singleton-Instanz zurück.

Warum wurde die Sprache so entworfen, dass n das exakt gleiche Objekt ist wie None ?

Wenn es keine Singleton-Instanz gab, konnten Sie sich nicht auf den Check x is None verlassen, da der Operator is auf der Identität basiert. Obwohl None == None auch True ist, ist es möglich, dass x == None be True ist, wenn x nicht tatsächlich None ist. Siehe diese Antwort für ein Beispiel.

Wie würde man dieses Verhalten in Python überhaupt umsetzen?

Sie können dieses Muster implementieren, indem Sie __new__ überschreiben. Hier ist ein einfaches Beispiel:

%Vor%

Ausgabe:

  

s1 ist s2: Wahres
  ID (s1): 4506243152
  ID (s2): 4506243152

Natürlich macht es dieses einfache Beispiel nicht unmöglich eine zweite Instanz zu erstellen.

    
Jake Cobb 31.12.2013, 21:07
quelle
3

Andere Antworten beschreiben, wie man __new__ benutzt, um ein Singleton zu implementieren, aber so ist None tatsächlich nicht implementiert (zumindest in cPython habe ich keine anderen Implementierungen betrachtet).

Der Versuch, eine Instanz von None bis type(None)() zu erstellen, ist speziell umkreist und führt zum Aufruf von folgende C-Funktion :

%Vor%

Und Py_RETURN_NONE ist hier definiert :

%Vor%

Vergleichen Sie dies mit der Funktion, die ein normales Python-Objekt erstellt :

%Vor%

Wenn Sie ein normales Objekt erstellen, wird Speicher für das Objekt zugewiesen und initialisiert. Wenn Sie versuchen, eine neue Instanz von None zu erstellen, erhalten Sie lediglich einen Verweis auf die bereits vorhandene _Py_NoneStruct . Deshalb ist jede Referenz auf None , egal was du tust, genau dasselbe Objekt.

    
Narcolei 31.12.2013 21:45
quelle
0
  1. Der NoneType überschreibt __new__ , die immer denselben Singleton zurückgeben. Der Code ist tatsächlich in C geschrieben , so dass dis nicht helfen kann, aber konzeptionell Es ist einfach so.

  2. Es ist einfacher, mit nur einer None-Instanz zu arbeiten. Sie sind alle gleich.

  3. Durch Überschreiben von __new__ ... z. B.

    %Vor%
kennytm 31.12.2013 21:03
quelle
0
  

Warum ist das exakt gleiche Objekt wie Keines?

Viele unveränderliche Objekte in Python sind interniert , einschließlich None , kleinere Ints und viele Strings.

Demo:

%Vor%
  

Warum wurde die Sprache entworfen?   so dass n das exakt gleiche Objekt wie None ist?

Siehe oben - Geschwindigkeit, Effizienz, Mangel an Mehrdeutigkeit und Speichernutzung unter anderen Gründen, um unveränderliche Objekte zu internieren.

  

Wie würde man überhaupt?   Implementieren Sie dieses Verhalten in Python?

Unter anderem können Sie __new__ überschreiben, um dasselbe Objekt zurückzugeben:

%Vor%

Für Zeichenfolgen können Sie intern auf Python 2 oder sys.intern auf Python 3

    
dawg 31.12.2013 21:08
quelle