Seite 1 von 1

Datenkapselung

Verfasst: Dienstag 17. Januar 2023, 09:06
von kiva
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)

Re: Datenkapselung

Verfasst: Dienstag 17. Januar 2023, 09:27
von /me
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.

Re: Datenkapselung

Verfasst: Dienstag 17. Januar 2023, 09:33
von Sirius3
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.

Re: Datenkapselung

Verfasst: Dienstag 17. Januar 2023, 09:41
von __blackjack__
@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()