2016-03-19 19 views
7

Ein Klassenkamerad fragte eine Frage über das Überschreiben der integrierten Klasse dict, und nach einigem Stochern wurde ich noch unsicherer.Warum wirkt sich die Neuzuweisung zu __builtins __. Dict nicht auf die Erstellung neuer Wörterbuchobjekte aus?

Nehmen Sie das integrierte dict. Ich kann dieses Variable zuweisen:

>>> dict=5 
>>> dict 
5 

Jetzt habe ich verloren Zugang zu dict (? Würde dies wie in C Shadowing wird ++ oder ist es anders), aber ich habe immer noch Zugriff auf die Klasse über builtins .dict. Aber ich kann das Überschreiben auch:

>>> __builtins__.dict = 6 
>>> __builtins__.dict 
6 

Aber auch dies nicht zu tun, die Klasse nicht bricht sich:

>>> stillDict = {'key': 'value'} 
>>> stillDict 
{'key': 'value'} 

Warum also die Klasse noch „arbeiten“, nachdem ich es beschattet habe? Woher weiß der Interpreter, dass ich ein Wörterbuch mit dieser Aufgabe mache, und wie wird das Wörterbuch aufgebaut, da es offensichtlich nicht wirklich __builtins__.dict erfordert?

bearbeiten dieser Punkt etwas weiter von Simeons Antwort, die sagt, es ist, weil ich ein Wörterbuch wörtliche ... und

vor dem Überschreiben, ich kann dies tun:

>>> a = dict() 
>>> a.items 
<built-in method items of dict object at 0x0000000002C97C08> 

nach dem Überschreiben dict und __builtins__.dict, kann ich dies tun:

>>> b = {} 
>>> b.items 
<built-in method items of dict object at 0x000000000288FC88> 

Welche führen s zu einer Folge ... Beide sind immer noch "dict objects", benutzt die dict-Klasse nur einen Konstruktor, um ein dict-Objekt zu erzeugen? Warum habe ich immer noch Zugriff auf die integrierten Methoden, nachdem ich die Klasse schattiert habe?

Antwort

4

{'key': 'value'} ist ein Dictionary-Literal, so dass weiterhin das Verhalten der Erstellung eines Wörterbuchs hat. Python muss nicht nachschauen, was dict bedeutet - es diesen Schritt überspringt und erzeugt direkt Bytecode ein Wörterbuch erstellen:

>>> def f(): {'a': 3} 
>>> import dis 
>>> dis.dis(f) 
    1   0 BUILD_MAP    1 
       3 LOAD_CONST    1 (3) 
       6 LOAD_CONST    2 ('a') 
       9 STORE_MAP 
      10 POP_TOP 
      11 LOAD_CONST    0 (None) 
      14 RETURN_VALUE 

Im Byte-Code geht es BUILD_MAP wie vor verwendet werden (dh es baut ein Karte/Wörterbuch basierend auf dem Code, den Sie geschrieben haben).

Die Bedeutung von dict hat sich geändert, wie Sie erwähnt haben.


In Bezug auf die Folgefrage: Sie die Wörterbuch-Klasse/Typ nicht beschattet haben - Sie haben sich verändert nur die Bedeutung dessen, was dict Mittel. Sie können den Dictionary-Typ nicht wegnehmen, und Python erzeugt ihn, wenn er ein Dictionary-Literal verwendet (z. B. {}).

Sobald Sie ein Objekt des Typs haben dict Sie den Zugriff auf seine Methoden haben (wie items()) - es ist nur, dass man es mit Syntax aufgebaut haben, anstatt einen Aufruf dict() (die Sie nicht beeinflussen können) (die Sie kann beeinflussen).

+0

Ich habe eine Follow-on-Bearbeitung hinzugefügt. –

+0

@DanielB.: Ihre Bearbeitung hat nichts geändert. 'dict' existiert immer noch in den Python-Interna, es ist einfach nicht zugänglich _by name_. Jede nicht-namenbasierte Methode für den Zugriff auf und die Verwendung eines 'dict' funktioniert weiterhin. – ShadowRanger

+0

@DanielB. Ich habe die Antwort diesbezüglich erweitert. –