6

Ich bin ein bisschen von diesem Verhalten verwechselt (Python 3.2):Python Doppelstrich Mangeln

class Bar: 
    pass 

bar = Bar() 
bar.__cache = None 
print(vars(bar))  # {'__cache': None} 

class Foo: 
    def __init__(self): 
     self.__cache = None 

foo = Foo() 
print(vars(foo))  # {'_Foo__cache': None} 

Ich habe ein bisschen auf nachlesen, wie doppelt Unterstreichen Attributnamen verursachen „verstümmelten“ zu sein, aber Ich hätte in beiden Fällen denselben Namen-Mangling erwartet.

What is the meaning of a single- and a double-underscore before an object name?

Irgendwelche Ideen, was hier vor sich geht?

+4

Der Punkt des Mangelns ist genau, um zu verhindern **, dass Ihr zweiter Fall richtig funktioniert. Die Absicht ist, das Attribut vor externem Code zu verbergen. – millimoose

Antwort

10

Namen Mangeln definiert wurde auftritt. Im Fall von Bar ist das Attribut __cache nicht als Teil der Klasse definiert, sondern wird nachträglich einem bestimmten Objekt hinzugefügt.

(Eigentlich, das möglicherweise nicht ganz korrekt seine Namensverkürzung bei der Auswertung des __new__ Verfahrens auftreten kann;.. Ich weiß nicht, aber egal, Ihr __cache explizit auf ein einzelnes Objekt hinzugefügt, nicht von dem Klassencode hinzugefügt .)

+4

Es ist während der Kompilierung entstellt. Sie können die Funktion 'dis.dis()' verwenden, um dies zu sehen, führen Sie einfach die 'import dis; dis.dis (Foo .__ init __) 'um zu sehen, dass der Name bereits entstellt wurde. –

+0

sehr hilfreich, danke für die Erklärung – gnr

7

Vom docs

Privat Namen Mangeln: Wenn eine Kennung, die in einer Klassendefinition textuell tritt mit zwei oder mehr Streichungszeichen beginnt und nicht in zwei oder mehr Unterstrichen zu beenden, ist es als ein privater Name dieser Klasse betrachtet. Private Namen werden in ein längeres Formular umgewandelt , bevor Code für sie generiert wird. Die Transformation fügt den Klassennamen vor dem Namen ein, wobei führende Unterstriche entfernt und ein einzelner Unterstrich vor dem Klassennamen eingefügt wird. Zum Beispiel wird der Bezeichner __spam, der in einer Klasse namens Ham auftritt, umgewandelt in _Ham__spam. Diese Transformation ist unabhängig von dem syntaktischen Kontext , in dem der Bezeichner verwendet wird. Wenn der umgewandelte Name extrem lang ist (länger als 255 Zeichen), kann Implementierung definiert abgeschnitten werden. Wenn der Klassenname nur aus Unterstrichen besteht, wird keine Transformation durchgeführt.

Sie Ihre Eigenschaft zuweisen, nachdem die Klasse während der Auswertung einer class Anweisung

+0

Der Link zur Dokumentation ist beschädigt –