Anfängerkurs in Python bei Coursera

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.
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

BlackJack hat geschrieben:@meego: Warum? Was ist an `spam.get_parrot()` übersichtlicher als `spam.parrot`? Das kann ich nicht nachvollziehen.
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

@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.
Benutzeravatar
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?
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

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 find's halt übersichtlicher, wenn es explizit als Methode daherkommt.
Warum soll alles was auf einem Objekt als Attribut vorhanden ist, aufrufbar sein?
Ich dachte, in Python wäre alles irgendwie als Attribut vorhanden.
Benutzeravatar
kbr
User
Beiträge: 1506
Registriert: Mittwoch 15. Oktober 2008, 09:27

meego hat geschrieben:Ich find's halt übersichtlicher, wenn es explizit als Methode daherkommt.
Du magst es gewohnt sein, aber vergleiche das folgende:

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
Bei kurzen Beispielen mag man die zusätzliche Methode und den damit einhergehenden umständlichen Aufruf ja noch verschmerzen, aber stelle Dir mal ein umfangreiches Programm vor, das auf diese Weise — ohne Mehrwert — künstlich aufgebläht wird.
BlackJack

@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:

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())
ist übersichtler als das hier

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?
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

BJ:
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.
Was fordere ich jetzt? Ich sehe Scotts Punkt da schon, grosse Programme würden dadurch erheblich stabiler.
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.
Codefolding?
Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
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.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

meego hat geschrieben:Was fordere ich jetzt? Ich sehe Scotts Punkt da schon, grosse Programme würden dadurch erheblich stabiler.
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:
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.
Codefolding?
Code der existiert muss gewartet werden.
meego hat geschrieben:
Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
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.
[/quote]

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.
BlackJack

@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.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
Ich habe mir jetzt mal verschiedene kleinere Projekte angeschaut (Sqalchemy, django, bottle, mercurial, numpy) Keines davon benutzt Getter oder Setter.
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
Versuch das mal mit Setter und Getter hinzubekommen. Übrigens so ähnlich auch in VBA für Excel zu schreiben, eine Sprache, die auch maximal gegen Getter eingestellt ist.
BlackJack

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.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
lunar

„Erwartungen brechen“?! Ohje, die armen Erwartungen… ;)
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Mit getter/setter wird alles viel schöner. Warum

Code: Alles auswählen

a = range(1,10,2)[2]
schreiben, wenn man doch auch ohne Zuweisungs- und Indexoperator auskommt:

Code: Alles auswählen

__main__.__dict__.__setitem__('a', range(2,10,2).__getitem__(2))
SCNR :twisted:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

@jerch? Wo kommt denn ``range`` plötzlich her, das solltest du aber ordentlich dereferenzieren :twisted:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ok, Ordnung muss sein:

Code: Alles auswählen

__main__.__dict__.__setitem__('range', __main__.__builtins__.range)
Jetzt hängt das builtin range an ... ehm ... range :lol:

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)
Toll, jetzt kann man getRange beliebig aufblasen für große Projekte ;)
(Nur wo kommt jetzt getattr her...)
Benutzeravatar
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 :roll:
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

cofi hat geschrieben:
meego hat geschrieben:
Und wozu bietet die Sprache Properties wenn man immer Getter und Setter schreiben würde?
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.
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.
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.

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.
lunar

@Darii Nun ja, Java hat mittlerweile try-with-resources als direktes Äquivalent zu "with".
meego
User
Beiträge: 380
Registriert: Montag 4. März 2013, 14:36

cofi hat geschrieben:Dazu braucht man keine Zugriffsrechte und schon gar keine Methoden, sondern allein Konventionen.
Solange sich jeder daran hält. :)
Java hat Properties, aber die bedeuten etwas anderes.
Was bedeuten sie anderes?
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.
Also doch Zwang? Mal sehen, ob ich mich dem unterwerfen will. :wink:
Antworten