grundlegene Frage zu Klassen/Methoden & Attributen

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
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

Eine ganz grundlegende Frage zum Thema Klassen, hier ein sinnfreies aber einfaches Beispiel:

Code: Alles auswählen

class Klasse:
    def __init__(self):
        self.t1 = "aaa"
        self.t2 = "bbb"
        self.t3 = "ccc"
        self.t4 = "ddd"

    def methode(self, attribut):
        attribut = attribut + "xxx"
        print (attribut)

                
instanz = Klasse()

Ich starte das Script und gebe dann an der Kommandozeile an:

Code: Alles auswählen

>>> print (instanz.t1)
aaa
der aktuelle Wert von "instanz.t1" wird dann wie erwartet ausgedruckt.

Jetzt rufe ich die Methode auf, mit einem Attribut t1, t2, t3 oder t4 als Parameter...

Code: Alles auswählen

>>> instanz.methode(instanz.t1)
aaaxxx
...der Wert von "attribut" wird ausgegeben. ABER:

...

wie erreiche ich jetzt, daß mein neuer Wert "aaaxxx" von "attribut" an "instanz.t1" wieder zurück übergeben wird, das jetzt also nicht

Code: Alles auswählen

>>> print (instanz.t1)
aaa
sondern

Code: Alles auswählen

>>> print (instanz.t1)
aaaxxx
erscheint?


Implizit wollte ich das schon mit meinen letzten beiden eröffneten Threads erfahren, aber eure Lösungen waren dann immer ganz anderer Art... aber ich stoße immer wieder darauf und daher nochmal die explizite Frage nach meinem Verständnisproblem.

Schonmal danke! :wink:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Code: Alles auswählen

    def methode(self, attribut):
        attribut = attribut + "xxx"
        return attribut

# und dann der Aufruf
instanz.t1 = instanz.methode(instanz.t1)
Wobei das imho sinnfrei ist:

Code: Alles auswählen

instanz.t1 += "xxx"
ist da doch viel einfacher ;-)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das Grundsaetzliche Problem ist aber, dass du da eine Funktion im Klassenrumpf hast, die eigentlich keine Methode ist bzw zu sein braucht.
Arbeite am besten mal den Teil zu Klassen im Tutorial durch.

Deine Funktion als Methode:

Code: Alles auswählen

class Klasse:
    def __init__(self):
        self.t1 = "aaa"
        self.t2 = "bbb"
        self.t3 = "ccc"
        self.t4 = "ddd"

    def methode(self, attribut):
        self.__dict__[attribut] += "xxx"
        return self.__dict__[attribut]
€: Bugfix.
Zuletzt geändert von cofi am Mittwoch 12. August 2009, 20:53, insgesamt 1-mal geändert.
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

Hyperion hat geschrieben:

Code: Alles auswählen

instanz.t1 += "xxx"
ist da doch viel einfacher ;-)
war auch nur ein Beispiel, das Addieren von strings soll hier nicht das Thema sein. :wink:

Hyperion hat geschrieben:

Code: Alles auswählen

    def methode(self, attribut):
        attribut = attribut + "xxx"
        return attribut

# und dann der Aufruf
instanz.t1 = instanz.methode(instanz.t1)
Ok, daß ich das durch ein "=" beim Aufruf hinbekomme, wusste ich. Kann ich das aber nicht auch "aus der Methode heraus" zuweisen?
Also ich weise ja zu instanz.t1 --> attribut beim Aufrufen der Methode
und möchte danach wieder attribut --> instanz.t1 innerhalb der Methode zurück zuweisen.
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

cofi hat geschrieben:Das Grundsaetzliche Problem ist aber, dass du da eine Funktion im Klassenrumpf hast, die eigentlich keine Methode ist bzw zu sein braucht.
Arbeite am besten mal den Teil zu Klassen im Tutorial durch.

Deine Funktion als Methode:

Code: Alles auswählen

class Klasse:
    def __init__(self):
        self.t1 = "aaa"
        self.t2 = "bbb"
        self.t3 = "ccc"
        self.t4 = "ddd"

    def methode(self, attribut):
        self.__dict__[attribut] += "xxx"
        return self.__dict__[attribut]
€: Bugfix.
mh, deines sagt:

Code: Alles auswählen

Traceback (most recent call last):
  File "<pyshell#55>", line 1, in <module>
    instanz.methode(instanz.t1)
  File "H:\Anwendungen\Phython 3.1\simpletest.py", line 9, in methode
    self.__dict__[attribut] += "xxx"
KeyError: 'aaa'
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

AntagonisT hat geschrieben:mh, deines sagt:

Code: Alles auswählen

Traceback (most recent call last):
  File "<pyshell#55>", line 1, in <module>
    instanz.methode(instanz.t1)
  File "H:\Anwendungen\Phython 3.1\simpletest.py", line 9, in methode
    self.__dict__[attribut] += "xxx"
KeyError: 'aaa'
Du musst das auch richtig aufrufen ...

Code: Alles auswählen

instanz.methode("t1")
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ick sehe eine Call-by-Value vs. Call-by-Reference Diskussion am Horizont erscheinen.... Python hat ausschließlich CbV und ich erkenne in der Methode "methode" den Versuch, etwas wie CbR zu wollen. Sagen wir liebe, es ist ein Meta-Programming-Problem und gesucht ist ein Weg, auf Attribute per Name zuzugreifen. Dann geht dies:

Code: Alles auswählen

class C:
    def m(self, name):
        setattr(self, name, getattr(self, name, "") + "xxx")
        
c = C()
c.m("foo")
c.m("foo")
print(c.foo)
Stefan
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

cofi hat geschrieben:
AntagonisT hat geschrieben:mh, deines sagt:

Code: Alles auswählen

Traceback (most recent call last):
  File "<pyshell#55>", line 1, in <module>
    instanz.methode(instanz.t1)
  File "H:\Anwendungen\Phython 3.1\simpletest.py", line 9, in methode
    self.__dict__[attribut] += "xxx"
KeyError: 'aaa'
Du musst das auch richtig aufrufen ...

Code: Alles auswählen

instanz.methode("t1")
huch!? Wie funktioniert das denn? :o
Das heißt, bei __dict__ kann ich meine Attribute einfach als string in "" übergeben? Das ist ja cool...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

``__dict__`` ist das Dict, das die Attribute des Objekts vorhaelt. Das soll jetzt aber keine Ermunterung sein das extensiv zu benutzen, sondern loest dein gestelltes Problem, das allerdings so nicht vorkommen sollte. Wenn doch, sollte man sich das besser gut ueberlegt haben.

@sma: Luegner! http://docs.python.org/tutorial/controlflow.html#id1 *duck*
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

sma hat geschrieben:Ick sehe eine Call-by-Value vs. Call-by-Reference Diskussion am Horizont erscheinen.... Python hat ausschließlich CbV und ich erkenne in der Methode "methode" den Versuch, etwas wie CbR zu wollen.
Ohne genau zu wissen, wovon du redest, habe ich das Gefühl, das es genau das ist, worauf ich hinaus will!
:P
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

cofi hat geschrieben:``__dict__`` ist das Dict, das die Attribute des Objekts vorhaelt. Das soll jetzt aber keine Ermunterung sein das extensiv zu benutzen, sondern loest dein gestelltes Problem, das allerdings so nicht vorkommen sollte. Wenn doch, sollte man sich das besser gut ueberlegt haben.
War mir ja fast schon klar, daß die Methode, die mir naheliegend und einleuchtend erscheint, schlechter Stil ist...
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

AntagonisT hat geschrieben:huch!? Wie funktioniert das denn? :o
Das heißt, bei __dict__ kann ich meine Attribute einfach als string in "" übergeben? Das ist ja cool...
Vergiss erstmal dass es __dict__ gibt, so lange bis du es wirklich brauchst, der kanonische Weg, Attribute zu dynamisch zu setzen/auszulesen, ist setattr bzw. getattr.

@cofi : Ist und bleibt prinzipiell cbv, auch wenn man dem Kind einen anderen, wohlklingenden Namen gibt. Genauso wie Java auch ausschließlich cbv kennt (aber ich will hier jetzt kein weiteres, fruchtloses Streitgespräch lostreten).
Zuletzt geändert von Darii am Mittwoch 12. August 2009, 22:38, insgesamt 1-mal geändert.
AntagonisT
User
Beiträge: 42
Registriert: Samstag 11. Juli 2009, 16:36

Darii hat geschrieben:
AntagonisT hat geschrieben:huch!? Wie funktioniert das denn? :o
Das heißt, bei __dict__ kann ich meine Attribute einfach als string in "" übergeben? Das ist ja cool...
Vergiss erstmal dass es __dict__ gibt, so lange bis du es wirklich brauchst, der kanonische Weg, Attribute zu dynamisch zu setzen/auszulesen, ist setattr bzw. getattr.
Ok, ich werde mir jetzt erstmal alles genau anschauen.

Danke an Alle!
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Antworten