Normalerweise will man ja eher nicht auf eine einzelne Variable zugreiffen. Wieso also bei Einzelattributen auf andere Konzepte ausweichen? Mir kommt das etwas inkonsistent vor.BlackJack hat geschrieben:@meego: Warum? Was ist an `spam.get_parrot()` übersichtlicher als `spam.parrot`? Das kann ich nicht nachvollziehen.
Anfängerkurs in Python bei Coursera
@meego: Sorry, das verstehe ich nicht. Natürlich will man auch auf einzelne Variablen zugreifen. Wenn Du `spam.get_parrot()` schreibst, dann willst Du ja auf den `parrot`-Wert zugreifen. Warum soll alles was auf einem Objekt als Attribut vorhanden ist, aufrufbar sein? Zumal das ja im Gegensatz zur Standardbibliothek und den meisten Modulen von Drittanbietern inkonsistent wäre. Denn dort gibt es ja nicht nur aufrufbare Objekte als Attribute.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Gehn wir mal einen Schritt zurueck: Getter, Setter und Attributszugriffe (von aussen) sind alle aus dem gleichen Grund schlecht: Man weiss zuviel ueber andere Klassen.
Stattdessen sollte man eben Methoden aufrufen, die auf dem Zustand operieren, so wie Gott^WAlan Kay das wollte.
Warum man nicht auf eine einzelne Variable (besser: Namen) zugreifen will, ist mir allerdings ein Raetsel. Was ist denn ein Getter, wenn nicht ein umstaendlicher Attributszugriff?
Stattdessen sollte man eben Methoden aufrufen, die auf dem Zustand operieren, so wie Gott^WAlan Kay das wollte.
Warum man nicht auf eine einzelne Variable (besser: Namen) zugreifen will, ist mir allerdings ein Raetsel. Was ist denn ein Getter, wenn nicht ein umstaendlicher Attributszugriff?
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Ich find's halt übersichtlicher, wenn es explizit als Methode daherkommt.BlackJack hat geschrieben:@meego: Sorry, das verstehe ich nicht. Natürlich will man auch auf einzelne Variablen zugreifen. Wenn Du `spam.get_parrot()` schreibst, dann willst Du ja auf den `parrot`-Wert zugreifen.
Ich dachte, in Python wäre alles irgendwie als Attribut vorhanden.Warum soll alles was auf einem Objekt als Attribut vorhanden ist, aufrufbar sein?
Du magst es gewohnt sein, aber vergleiche das folgende:meego hat geschrieben:Ich find's halt übersichtlicher, wenn es explizit als Methode daherkommt.
Code: Alles auswählen
class Car(object):
color = 'red'
def get_color():
return self.color
my_car = Car()
print my_car.get_color()
# versus:
class Car(object):
color = 'red'
my_car = Car()
print my_car.color
@meego: Objekte haben Attribute, aber nicht jedes Attribut ist aufrufbar. Genau das forderst Du aber weil das übersichtlicher sein soll. Letztendlich forderst Du das es Datenattribute geben müsste, die man nicht direkt abrufen kann. Also zumindest nicht ausserhalb von Methoden auf dem Objekt.
Wie stehst Du zu der Aussage das die vielen dann nötigen trivialen Getter und Setter den Quelltext einer Klasse nur unnötig aufblähen und damit unübersichtlicher machen, weil man diesen Boilerplate-Code immer ignorieren muss, beziehungsweise genau hinschauen muss, ob die wirklich trivial sind, oder vielleicht doch etwas machen? Und innerhalb von Methoden auf der Klasse muss man sich dann immer entscheiden ob man auf das Attribut direkt zugreift, oder über die Getter/Setter.
Das hier:
ist übersichtler als das hier
?
Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
Wie stehst Du zu der Aussage das die vielen dann nötigen trivialen Getter und Setter den Quelltext einer Klasse nur unnötig aufblähen und damit unübersichtlicher machen, weil man diesen Boilerplate-Code immer ignorieren muss, beziehungsweise genau hinschauen muss, ob die wirklich trivial sind, oder vielleicht doch etwas machen? Und innerhalb von Methoden auf der Klasse muss man sich dann immer entscheiden ob man auf das Attribut direkt zugreift, oder über die Getter/Setter.
Das hier:
Code: Alles auswählen
class A(object):
def __init__(self):
self._spam = 42
self._parrot = 23
def get_spam(self):
return self._spam
def set_spam(self, value):
self._spam = value
def get_parrot(self):
return self._parrot
def set_parrot(self, value):
self._parrot = value
def modify(self):
self.set_parrot(self.get_parrot() * 2 + self.get_spam())
Code: Alles auswählen
class A(object):
def __init__(self):
self.spam = 42
self.parrot = 23
def modify(self):
self.parrot = self.parrot * 2 + self.spam
Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
BJ:
Was fordere ich jetzt? Ich sehe Scotts Punkt da schon, grosse Programme würden dadurch erheblich stabiler.Objekte haben Attribute, aber nicht jedes Attribut ist aufrufbar. Genau das forderst Du aber weil das übersichtlicher sein soll. Letztendlich forderst Du das es Datenattribute geben müsste, die man nicht direkt abrufen kann.
Codefolding?Wie stehst Du zu der Aussage das die vielen dann nötigen trivialen Getter und Setter den Quelltext einer Klasse nur unnötig aufblähen und damit unübersichtlicher machen.
Java wird auch Properties haben. Die Frage scheint mir eher, wie sehr man auf OOP setzt und ob man alleine oder in einem Team an etwas arbeitet.Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ich sehe den Punkt dagegen nicht, warum soll denn ein Attributszugriff durch eine Methode passieren? Große Programme werden nicht durch mehr Methoden stabiler, sondern dadurch dass man Zuständigkeiten absteckt. Dazu braucht man keine Zugriffsrechte und schon gar keine Methoden, sondern allein Konventionen.meego hat geschrieben:Was fordere ich jetzt? Ich sehe Scotts Punkt da schon, grosse Programme würden dadurch erheblich stabiler.
Code der existiert muss gewartet werden.meego hat geschrieben:Codefolding?Wie stehst Du zu der Aussage das die vielen dann nötigen trivialen Getter und Setter den Quelltext einer Klasse nur unnötig aufblähen und damit unübersichtlicher machen.
[/quote]meego hat geschrieben:Java wird auch Properties haben. Die Frage scheint mir eher, wie sehr man auf OOP setzt und ob man alleine oder in einem Team an etwas arbeitet.Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
Java hat Properties, aber die bedeuten etwas anderes. Java hat dagegen nichts mit dem man Attributszugriffe transparent durch Funktionen bzw Funktionsaufrufe ersetzen kann.
Das Problem hat nichts mit OOP im eigentlichen Sinne zu tun, sondern ganz allgemein mit dem Arbeiten mit Abstraktionen und Schnittstellen. Man arbeitet nicht deshalb objektorientiert, weil man Getter und Setter hat.
Letztendlich muss man auf den Boden zurückkommen und einsehen: Wir arbeiten mit Python und Python hat keine Zugriffsbeschränkungen für Attribute. Wenn man dennoch darauf beharrt, arbeitet man gegen die Sprache und gegen die Community, die auf Konvention setzt.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@meego: Mir ist kein Editor bekannt der solches Code-Folding beherrscht. Und wenn man triviale Getter und Setter durch Code-Folding wieder ausblenden muss, warum muss man sie denn dann überhaupt *schreiben*. Du sagst doch durch den Boilerplate-Code wird es übersichtlicher. Wenn es übersichtlich wäre, müsste man es doch nicht ausblenden, denn es wäre ja übersichtlicher wenn es *da* ist.
Java hat keine Properties im Sinne von Python (oder C#, D, Vala). Genau *deswegen* schreibt man in Java ja auch triviale Getter und Setter. Nur deshalb ist das dort notwendig wenn man den Code mal ändern will ohne das sich die Schnittstelle nach aussen ändert.
Java hat keine Properties im Sinne von Python (oder C#, D, Vala). Genau *deswegen* schreibt man in Java ja auch triviale Getter und Setter. Nur deshalb ist das dort notwendig wenn man den Code mal ändern will ohne das sich die Schnittstelle nach aussen ändert.
Ich habe mir jetzt mal verschiedene kleinere Projekte angeschaut (Sqalchemy, django, bottle, mercurial, numpy) Keines davon benutzt Getter oder Setter.meego hat geschrieben:[…] grosse Programme würden dadurch erheblich stabiler.
[…] Die Frage scheint mir eher, wie sehr man auf OOP setzt und ob man alleine oder in einem Team an etwas arbeitet.
Im Gegenteil: vielfach wird versucht, möglichst viel wie einen Attributzugriff aussehen zu lassen, weil es die bequemste und übersichtlichste Art ist Informationen abzufragen oder zu setzen.
Weil ich es neulich in meiner Excel-Klasse hatte (nicht gerade schön aber für Datenhaltungsklassen praktisch):
Code: Alles auswählen
cell.border.left.color = cell.border.right.color = Color.red
Weil Sirius3 gerade anmerkte das einige Projekte so viel wie möglich versuchen als Datenattribute erscheinen zu lassen: Die in Java geschriebene Python-Implementierung Jython kann ja von Python-Code aus Java-Objekte verwenden und da wird die Java-typische Getter/Setter-Namenskonvention in Attribute umgesetzt. Wenn man also eine Java-Klasse mit `getFoo()`- und/oder `setFoo()`-Methoden hat, dann kann man von Python aus einfach auf das Attribut `foo` zugreifen und im Hintergrund wird dann die entsprechende Methode aufgerufen.
Man sollte auch Bedenken dass es auch in Python durchaus Gründe dafür gibt getter bzw. setter zu haben, z.B. wenn Nebeneffekte involviert sind. Das führt zu einer Gewissen Erwartung wenn getter oder setter auftauchen, die gebrochen wird wenn jemand diese nutzt nur weil ihm/ihr properties nicht gefallen.
Mit getter/setter wird alles viel schöner. Warumschreiben, wenn man doch auch ohne Zuweisungs- und Indexoperator auskommt: SCNR 
Code: Alles auswählen
a = range(1,10,2)[2]
Code: Alles auswählen
__main__.__dict__.__setitem__('a', range(2,10,2).__getitem__(2))

Ok, Ordnung muss sein:Jetzt hängt das builtin range an ... ehm ... range 
Edit:
Tss, da könnte das range aus __builtins__ ja wieder ein property sein, was unsicher ist. Hmm, vllt so:
Toll, jetzt kann man getRange beliebig aufblasen für große Projekte 
(Nur wo kommt jetzt getattr her...)
Code: Alles auswählen
__main__.__dict__.__setitem__('range', __main__.__builtins__.range)

Edit:
Tss, da könnte das range aus __builtins__ ja wieder ein property sein, was unsicher ist. Hmm, vllt so:
Code: Alles auswählen
__builtins__.__dict__.__setitem__('getRange', getattr(__builtins__, 'range'))
__main__.__dict__.__setitem__('range', __builtins__.getRange)

(Nur wo kommt jetzt getattr her...)
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Also mir gefaellt ja dieser Attributszugriff auf `__dict__` gefaellt mir gar nich 

Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Das ist etwas was man nicht genug betonen kann. Der einzige Grund, warum man getter und setter bei Java zwingend braucht, ist einzig und allein die Tatsache dass man einen Attributzugriff nicht transparent durch einen Methodenzugriff ersetzen kann. Will man nun den Attributzugriff verhindern, muss man zwangsläufig die Schnittstelle des Objektes ändern. Genau deswegen wird von Leuten mit Java/C++/etc.-Vorbildung auch oft behauptet dass direkter Attributzugriff unsauber ist. Weil das stimmt – für Java/etc.cofi hat geschrieben:Java hat Properties, aber die bedeuten etwas anderes. Java hat dagegen nichts mit dem man Attributszugriffe transparent durch Funktionen bzw Funktionsaufrufe ersetzen kann.meego hat geschrieben:Java wird auch Properties haben. Die Frage scheint mir eher, wie sehr man auf OOP setzt und ob man alleine oder in einem Team an etwas arbeitet.Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
Das Problem hat nichts mit OOP im eigentlichen Sinne zu tun, sondern ganz allgemein mit dem Arbeiten mit Abstraktionen und Schnittstellen. Man arbeitet nicht deshalb objektorientiert, weil man Getter und Setter hat.
Wenn man man nicht will, dass auf ein Attribut zugegriffen werden soll, verwendet "_" oder "__" je nach Bedarf. Wer dann trotzdem drauf zugreift muss wissen was er tut und sich nicht wundern, wenn alles explodiert.
Einem mag das widersprüchlich erscheinen, aber Python macht es einem imo durch Sprachkonstrukte wie z.B. "with" einfacher als Java saubere Programme zu schreiben. "finalize()" ist nicht verlässlich, "with" schon.
@Darii Nun ja, Java hat mittlerweile try-with-resources als direktes Äquivalent zu "with".
Solange sich jeder daran hält.cofi hat geschrieben:Dazu braucht man keine Zugriffsrechte und schon gar keine Methoden, sondern allein Konventionen.

Was bedeuten sie anderes?Java hat Properties, aber die bedeuten etwas anderes.
Also doch Zwang? Mal sehen, ob ich mich dem unterwerfen will.Letztendlich muss man auf den Boden zurückkommen und einsehen: Wir arbeiten mit Python und Python hat keine Zugriffsbeschränkungen für Attribute. Wenn man dennoch darauf beharrt, arbeitet man gegen die Sprache und gegen die Community, die auf Konvention setzt.
