Seite 1 von 1

private Attribute

Verfasst: Mittwoch 29. April 2020, 21:18
von PyTimmi
Hallo zusammen,

ich habe gelesen, dass es unter Python-Entwicklern eine Konvention gibt, nach der man von außen nicht direkt auf ein Attribut zugreift, dass mit einem einfachen Unterstrich als Präfix benannt wurde.
Man kann es aber wohl theor. trotzdem machen.

Weiterhin habe ich gelesen, dass man tatsächlich nicht von außen auf ein Attribut zugreifen kann, dass mit dem Präfix doppelter Unterstrich benannt wurde.
Aber ich hab es getestet, man kann es doch.

Worin liegt dann der Unterschied zwischen dem doppelten und dem einfachen Unterstrich?
Und schützt man Attribute dann mit der Built-in Funktion "property"?

Danke und Gruß

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 21:26
von __deets__
Der doppelte erzeugt eben komplizierteren Namen, der dafür sorgt, dass es nicht zu einer Namenskollision kommen kann. Das kann bei Vererbung und sehr generischen Attributen theoretisch vorkommen. Praktisch habe ich seit Jahren keine doppelten unterstriche mehr verwandt.

Und zur zweiten frage: klares nein. Wenn es nur um normalen Attribut-Zugriff geht, ist es eben ein ohne unterstrich geschriebenes, öffentliches Attribut.

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 22:03
von PyTimmi
Ok, danke schon mal für die Antwort.
Was ich aber noch nicht verstehe ist, warum überall zu lesen ist, dass Attribute beginnend mit zwei Unterstrichen private sind und von außen nicht geändert werden können.
Das hab ich ausprobiert und es klappt sehr wohl :D

Code: Alles auswählen

class Auto:
    def __init__(self, farbe, leistung):
        self.__farbe = farbe
        self.__leistung = leistung

traumauto = Auto("rot",300)
traumauto.__farbe = "blau"
Wenn ich mir dann die Farbe des Traumautos per print ausgeben lasse, dann kommt blau.

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 22:08
von __deets__
Das ist aber nicht richtig. Schreib mal eine Methode auf der Klasse, die das Attribut benutzt, zb einfach printed. Und rief die mal auf, nach deiner Zuweisung. Die ist immer noch rot. Garantiert.

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 22:11
von PyTimmi

Code: Alles auswählen

class Auto:
    def __init__(self, farbe, leistung):
        self.__farbe = farbe
        self.__leistung = leistung
    
    def farbe_ausgeben(self):
        print(self.__farbe)
​
traumauto = Auto("rot",300)
traumauto.__farbe = "blau"
traumauto.farbe_ausgeben()
Ergebnis: rot

Tatsache. Aber was passiert denn dann in dieser Zeile:

Code: Alles auswählen

traumauto.__farbe = "blau"

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 22:15
von __deets__
Du bindest ein Attribut mit dem Namen an [die Klasse] - Korrektur, das Objekt natürlich 🤦‍♂️. Gib dir mal traumauto.__dict__ aus, dann siehst, was da hinter den Kulissen passiert.

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 22:34
von PyTimmi
{'_Auto__farbe': 'rot', '_Auto__leistung': 300, '__farbe': 'blau'}

Das neue Attribut gehört also quasi gar nicht richtig dazu?

Re: private Attribute

Verfasst: Mittwoch 29. April 2020, 23:02
von __blackjack__
Um noch mal zu dem Schutz zu kommen: Man macht das in Python einfach nicht. Man schreibt *einen* führenden Unterstrich und verlässt sich darauf das Leute das respektieren. Wer das nicht respektiert und damit auf Nase fällt, ist halt selbst Schuld.

Re: private Attribute

Verfasst: Donnerstag 30. April 2020, 06:45
von __deets__
Doch, das neue Attribut gehört dazu. Aber kann von in der Klasse nicht einfach benutzt werden. Der Mechanismus versieht alle Attribute mit __ mit einem Klassen-Namen-Präfix. Das wird rein lexikalisch erledigt, der parser weiß ja, wo im Quellcode er ist. Und generiert eben Code, der immer diesen Präfix nutzt. Und damit ist das einfach zu nutzen, aber recht sicher vor kollisionen. Man KANN aber rankommen. Denn du kannst ja den zu sehenden vollen Namen benutzen. Dann kannst du das also auch ändern. Es ist also keine sicherer kapselung.

Und bevor du jetzt zu dem Schluss kommst “aber dann kann ich das ja immer benutzen!” - nein. Es gibt subtile Fehler, die man sich damit einfängt, weil man eben so wie du schon gesehen hast, gar nicht bemerkt, dass man ein neues Attribut anlegt, statt ein bestehendes zu updated. Und im Kontext von Vererbung landet man dann damit auf der Nase. Und wundert sich.