2016-03-25 5 views
1

betrachten den folgenden Code:Können private Python-Variablen auch geändert werden, ohne object._className__attributeName zu verwenden?

class animal: 
    def __init__(self, name): 
     self.__name = name 

class dog(animal): 
    def __init__(self, owner, name): 
     self.__owner = owner 
     super(dog, self).__init__(name) 

terrier = dog('A', 'B') 
terrier.owner = 'C' 
terrier.name = 'D' 
print(terrier._dog__owner, terrier._animal__name) 
print(terrier.owner, terrier.name) 

Die Ausgabe lautet:

A B 
C D 

Ich verstehe, dass Python private Variablen nur durch Konvention geschützt sind. Aber alle anderen Threads erwähnen ._className__attributeName zB. terrier._dog__owner als einzige Möglichkeit, variable Werte zu ändern. Hier kann ich sie sogar mit terrier.owner oder terrier.name ändern.

Seltsamerweise geben beide einen anderen Ausgang wie oben gezeigt. So erstellen terrier.owner oder terrier.name verschiedene Instanzen von terrier._dog__name oder terrier._animal__name? Was genau ist hier passiert?

+1

Ja. In Python gibt es keine privaten Attribute. –

+1

Ja, "terrier.owner" ist ein anderer Name als "terrier._dog__owner". Warum würdest du anders denken? Es ist nicht anders als 'terrier.blah = "foo" 'zu machen. Sie können beliebige Attribute erstellen, die Sie möchten. – BrenBarn

+0

Danke, aber können Sie erklären, warum die beiden getrennten Instanzen von Objektterrier erstellt werden, die zwei verschiedene Sätze von Ausgängen ergeben? –

Antwort

1

Double-Undercore-Variablen sind in der Tat nicht privat die Art und Weise Java oder C++ siehe Datenschutz. Sie sind nicht dazu gedacht, außerhalb der Klasse als privat zu codieren. Sie sind gewohnt, Namenskonflikte unter Unterklassen zu vermeiden, weshalb der Klassenname als Präfix verwendet wird.

z. Wenn Sie eine interne Implementierung für eine Klasse Foo haben und die Unterklasse Bar(Foo) nicht versehentlich dieselben Namen in ihrer Implementierung verwenden soll, können Sie das Attribut __spam verwenden, das in _Foo__spam bzw. _Bar__spam umgewandelt und somit gewonnen wird Komm nicht zusammen.

Die terrier.owner und terrier.name Attribute hinzugefügt sind unabhängige und haben nichts mit den _dog__owner und _animal__name Attribute von Klassen verwendet zu tun. Die Verwendung doppelter Unterstrich-Variablennamen verhindert nicht, dass andere Attribute erstellt werden, einschließlich des gleichen Namens ohne Unterstriche.

+0

Kommend von Java dachte ich Terrier .__ Besitzer ist eine private Version von terrier.owner. Sie sind unabhängig, haben aber keinerlei Beziehung zueinander. Ich habs. –