Parameterübergabe bei Methoden

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
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Hallo zusammen,

ich habe in einer Klasse zwei Methoden, die fast das gleiche machen. Nur hat eine Methode ein Übergabeparameter mehr. Eine Methode holt sich die Farbe des Objekts über get_color(), die andere bekommt eine andere Farbe übergeben. Diese beiden Methoden wollte ich zusammenfassen, indem ich dem zusätzlichen Parameter self.get_color() als Default übergebe, bekomme das aber leider nicht hin.
Hier ein kurzes Beispiel wie ich mir das vorgestellt hatte:

Code: Alles auswählen

class ColorFields:
    def __init__(self, color):
        self.color = color

    def get_color(self):
        return self.color()

    def manipulate_color(self, new_color=self.get_color()):
        print(new_color)


def main():
    color_field = ColorFields('green')
    color_field.manipulate_color()
    color_field.manipulate_color('blue')

if __name__ == '__main__':
    main()
Als Fehlermeldung erhalte ich:

Code: Alles auswählen

Traceback (most recent call last):
  File "F:/Python_Code/Tests/self_transfer/main.py", line 1, in <module>
    class ColorFields:
  File "F:/Python_Code/Tests/self_transfer/main.py", line 8, in ColorFields
    def manipulate_color(self, new_color=self.get_color()):
NameError: name 'self' is not defined
Kann mir jemand sagen wie man das richtig umsetzt?

Schon mal vielen Dank!
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da sind eine ganze Reihe von Fehlern drin. Du rufst zB self.color auf, und das ist ein String - das geht in die Hose.

Zu deiner eigentlichen Frage: die Default-Argumente einer Funktion/Methode werden nur *EINMAL* ausgerechnet, beim erzeugen der besagten Funktion. Also zu dem Zeitpunkt, bei dem der Interpreter deinen Quellcode einliest.

Damit scheitert dein Versuch, eine Methode aufzurufen. Das musst du schon explizit machen, indem du zB dein color-Argument per default auf "None" setzt, und dann ggf. etwas spezielles machst, wenn der Benutzer das nicht anders angegeben hat:

Code: Alles auswählen

def foobar(color=None):
      if color is None:
             tu_was()
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Was spricht dagegen, direkt auf das Attribut 'color' zuzugreifen? Was Du da formuliert hast, sind triviale getter- und setter-Methoden.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

__deets__ hat geschrieben:Da sind eine ganze Reihe von Fehlern drin. Du rufst zB self.color auf, und das ist ein String - das geht in die Hose.
Die Klammern am Ende von Zeile 6 haben dort natürlich nichts zu suchen. Sorry, da habe ich nicht aufgepasst...
__deets__ hat geschrieben:Zu deiner eigentlichen Frage: die Default-Argumente einer Funktion/Methode werden nur *EINMAL* ausgerechnet, beim erzeugen der besagten Funktion. Also zu dem Zeitpunkt, bei dem der Interpreter deinen Quellcode einliest.
Gut zu wissen! Dann ist klar, warum mein Versuch nicht funktionieren konnte.

@__deets__ und bwbg:
'None' habe ich schon öfters erfolgreich benutzt. Nur dachte ich diesmal ich könnte mir die if-Bedingung sparen, wenn ich get_color() direkt als Default übergebe. Aber jetzt weiß ich ja, warum das so nicht geht :)

Danke für die Antworten!
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Ich reduziere Dein Beispiel provokant auf das m. E. notwendige :wink: :

Code: Alles auswählen

color = 'green'
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

@bwbg: Eine Minimalantwort auf ein Minimalbeispiel...
Das nächste mal werde ich extra für dich kein Minimalbeispiel erstellen, sondern mehrere hundert Zeilen Code posten :wink:
Antworten