Datenkapselung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kiva
User
Beiträge: 1
Registriert: Dienstag 27. September 2022, 15:31

Hallo Users.. ich habe eine frage, warum bekomme ich keine Fehler?
Danke.

class Fahrzeug:
def __init__(self, name):
self.__name = name
self.__geschwindigkeit = 23

def ausgabe(self):
print("Das Fahrzeig ", self.__name, " hat Folgende Eingeschaften")
print("Geschwindigkeit: ", self.__geschwindigkeit)

auto = Fahrzeug("VW")
auto.ausgabe()

auto.__geschwindigkeit = 10
print("Geschwindigkeit- ", auto.__geschwindigkeit)
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Du setzt von außen `auto.__geschwindigkeit = 10`. Setz mal vor und hinter die Zeile ein `print(dir(auto))` und schau dir an, welche Attribute `auto` jeweils hat.
Sirius3
User
Beiträge: 18275
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum erwartest Du einen Fehler?

Doppelte Unterstriche benutzt man nur in äußerst seltenen Fällen, mit Mehrfachvererbung (die man aber eh nur sehr selten einsetzen sollte).
Wenn Du irgendwo gelesen hast, dass doppelte Unterstriche dem entspricht, was andere Programmiersprachen als private bezeichnen, dann ist das falsch.
Du hast nur ein neues Attribut auto.__geschwindigkeit angelegt, das nicht mit dem Attribut auto._Fahrzeug__geschwindigkeit kollidiert, dafür sind ja die __ da.

Korrektes Python wäre

Code: Alles auswählen

class Fahrzeug:
    def __init__(self, name):
        self._name = name
        self._geschwindigkeit = 23

    def ausgabe(self):
        print(f"Das Fahrzeig {self._name} hat Folgende Eingeschaften")
        print("Geschwindigkeit: ", self._geschwindigkeit)
wenn die Attribute nicht von außen geändert werden sollen, oder

Code: Alles auswählen

class Fahrzeug:
    def __init__(self, name):
        self._name = name
        self.geschwindigkeit = 23

    def ausgabe(self):
        print(f"Das Fahrzeig {self._name} hat Folgende Eingeschaften")
        print("Geschwindigkeit: ", self.geschwindigkeit)
wenn man `geschwindigkeit` von außen setzen können soll.
Benutzeravatar
__blackjack__
User
Beiträge: 14067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kiva: Ersetze die doppelten führenden Unterstriche durch *einen* führenden Unterstrich. Die doppelten bedeuten nicht ”private”, sondern sind dafür da um Namenskollisionen bei Mehrfachvererbung oder tiefen Vererbungshierarchien zu vermeiden. Beides macht man eigentlich nicht, dementsprechend selten braucht man tatsächlich die doppelten Unterstriche. *Ein* Unterstrich ist die Namenskonvention für Implementierungsdetails auf die von aussen nicht zugegriffen werden sollte.

`ausgabe()` sollte eher `ausgeben()` heissen, weil Funktionen und Methoden üblicherweise nach Tätigkeiten benannt werden, damit der Leser weiss was die tun, und um sie einfacher von eher passiven Werten unterscheiden zu können.

Code: Alles auswählen

#!/usr/bin/env python3


class Fahrzeug:
    def __init__(self, name):
        self._name = name
        self._geschwindigkeit = 23

    def ausgeben(self):
        print("Das Fahrzeug", self._name, "hat folgende Eingeschaften")
        print("Name:", self._name)
        print("Geschwindigkeit:", self._geschwindigkeit)


def main():
    auto = Fahrzeug("VW")
    auto.ausgeben()

    auto._geschwindigkeit = 10
    print("Geschwindigkeit:", auto._geschwindigkeit)


if __name__ == "__main__":
    main()
Wobei man das ja eigentlich nicht machen sollte, auf Interna von aussen zugreifen. Die Frage ist, warum das dann überhaupt so markiert ist, wenn man das dann doch von aussen ändern will/muss.

Bevor dann gleich das nächste ”unpythonische” gemacht wird: Man schreibt in Python keine trivialen Getter/Setter-Methoden, sondern greift dann einfach auf ein öffentliches Attribut zu. Wenn man das später mal ändern will, gibt es `property()`.

Code: Alles auswählen

#!/usr/bin/env python3


class Fahrzeug:
    def __init__(self, name):
        self._name = name
        self.geschwindigkeit = 23

    def ausgeben(self):
        print("Das Fahrzeug", self._name, "hat folgende Eingeschaften")
        print("Name:", self._name)
        print("Geschwindigkeit:", self.geschwindigkeit)


def main():
    auto = Fahrzeug("VW")
    auto.ausgeben()

    auto.geschwindigkeit = 10
    print("Geschwindigkeit:", auto.geschwindigkeit)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten