Matroids Matheplanet Forum Index
Moderiert von matph
Informatik » Programmieren » Python: Ausgabe privates Attribut nach Vererbung
Autor
Universität/Hochschule Python: Ausgabe privates Attribut nach Vererbung
Spedex
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 19.03.2020
Mitteilungen: 1024
Wohnort: Wien / Bayern
  Themenstart: 2021-01-18

Hallo, folgender Code: \sourceon Python class Haus: Anzahl_Haus = 0 def __init__(self, Adresse, Hoehe, Etagenanzahl): self.__Adresse = Adresse self.Hoehe = Hoehe self.Etagenanzahl = Etagenanzahl Haus.Anzahl_Haus += 1 def get_Adresse(self): return(self.__Adresse) def __str__(self): return(f"Adresse: {self.__Adresse}, Höhe: {self.Hoehe}, Etagenanzahl: {self.Etagenanzahl}") def __lt__(self, other): return(self.Hoehe < other.Hoehe) class Wolkenkratzer(Haus): Anzahl_Wolkenkratzer = 0 def __init__(self, Adresse, Hoehe, Etagenanzahl, Name): self.Name = Name Haus.__init__(self, Adresse, Hoehe, Etagenanzahl) Wolkenkratzer.Anzahl_Wolkenkratzer += 1 def __str__(self): return(f"Name: {self.Name}, Adresse: {self.__Adresse} \ Hoehe: {self.Hoehe}, Etagenanzahl: {self.Etagenanzahl}") \sourceoff Man sieht, dass die Klasse Wolkenkratzer von der Klassen Haus erbt. In beiden Klasse befindet sich die Methode __init__. Doch die Ausgabe der Adresse mittels print(Klasse) funktioniert nur bei der Haus, jedoch nicht bei Wolkenkratzer. Wenn ich die Adresse bei Wolkenkratzer ausgeben möchte, muss ich anstelle von self.__Adresse self.get_Adresse() schreiben. Meine Frage: Wieso ist das so, wieso funktioniert es bei der einen Klasse schon und bei der anderen (vererbten) Klasse nicht? Liebe Grüße Spedex


   Profil
DerEinfaeltige
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 11.02.2015
Mitteilungen: 3000
  Beitrag No.1, eingetragen 2021-01-20

Das private Attribut heißt (extern) nicht __Adresse, sondern _Haus__Adresse. \sourceon Python class Haus: Anzahl_Haus = 0 def __init__(self, Adresse, Hoehe, Etagenanzahl): self.__Adresse = Adresse self.Hoehe = Hoehe self.Etagenanzahl = Etagenanzahl Haus.Anzahl_Haus += 1 def get_Adresse(self): return(self.__Adresse) def __str__(self): return(f"Adresse: {self.__Adresse}, Höhe: {self.Hoehe}, Etagenanzahl: {self.Etagenanzahl}") def __lt__(self, other): return(self.Hoehe < other.Hoehe) class Wolkenkratzer(Haus): Anzahl_Wolkenkratzer = 0 def __init__(self, Adresse, Hoehe, Etagenanzahl, Name): self.Name = Name Haus.__init__(self, Adresse, Hoehe, Etagenanzahl) Wolkenkratzer.Anzahl_Wolkenkratzer += 1 def __str__(self): return(f"Name: {self.Name}, Adresse: {self._Haus__Adresse} \ Hoehe: {self.Hoehe}, Etagenanzahl: {self.Etagenanzahl}") H = Haus("Schlangengrube 9", 12, 3) W = Wolkenkratzer("Wolke 7", 120, 30, "Turm von Hanoi") print(H) print(W) \sourceoff


   Profil
Spedex
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 19.03.2020
Mitteilungen: 1024
Wohnort: Wien / Bayern
  Beitrag No.2, vom Themenstarter, eingetragen 2021-01-20

Ah, ok. Gut, danke für die Erklärung! Liebe Grüße Spedex


   Profil
__blackjack__
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.09.2021
Mitteilungen: 41
  Beitrag No.3, eingetragen 2021-09-26

@Spedex: Es gibt in Python kein ”private”. Die doppelten führenden Unterstriche sind nicht dazu da ”private” aus anderen Programmiersprachen zu simulieren, sondern um Namenskollisionen bei tiefen Vererbungshierarchien und/oder Mehrfachvererbung zu verhindern. Da man beides selten bis gar nicht macht, braucht man auch selten bis gar nicht diese beiden Unterstriche. Implementierungsdetails werden in Python mit *einem* führenden Unterstrich gekennzeichnet. Allerdings hättest Du das Problem gar nicht, wenn Du nicht Code (und Daten) wiederholen würdest, was man so nicht machen würde. Die Zeichenkettendarstellung von `Wolkenkratzer` ist ja nicht komplett neu, sondern nur die von `Haus` um einen Präfix erweitert. Da schon Code existiert der ein `Haus` als Zeichenkette repräsentiert, sollte man den einfach aufrufen, statt das alles noch mal hin zu schreiben. Statt trivialer Getter gibt es in Python berechnete Attribute a.k.a. Properties. \sourceon python \numberson class Haus: hausanzahl = 0 def __init__(self, adresse, hoehe, etagenanzahl): self._adresse = adresse self.hoehe = hoehe self.etagenanzahl = etagenanzahl Haus.hausanzahl += 1 @property def adresse(self): return self._adresse def __str__(self): return ( f"Adresse: {self.adresse}, Höhe: {self.hoehe}," f" Etagenanzahl: {self.etagenanzahl}" ) def __lt__(self, other): return self.hoehe < other.hoehe class Wolkenkratzer(Haus): wolkenkratzeranzahl = 0 def __init__(self, adresse, hoehe, etagenanzahl, name): self.name = name Haus.__init__(self, adresse, hoehe, etagenanzahl) Wolkenkratzer.wolkenkratzeranzahl += 1 def __str__(self): return f"Name: {self.name}, {Haus.__str__(self)}" \sourceoff Die Klassenvariablen zum zählen sind relativ unsinnig und globale Variablen == Böse. Wenn man die Anzahlen im Auge behalten will, macht man das explizit, beispielsweise wenn man alle Gebäude in eine Datenstruktur steckt und schaut wie gross die ist. Nur `__lt__()` zu implementieren ist komisch weil sich der Typ dann bezüglich der anderen Vergleichsoperatoren unerwartet verhält. Die Höhe als ”natürliches” Vergleichskriterium zu definieren ist IMHO auch etwas schräg. Kommt natürlich auf den Anwendungsfall an.


   Profil
Spedex hat die Antworten auf ihre/seine Frage gesehen.
Spedex wird per Mail über neue Antworten informiert.

Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2021 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]