Seite 1 von 1

grundlegene Frage zu Klassen/Methoden & Attributen

Verfasst: Mittwoch 12. August 2009, 20:07
von AntagonisT
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:

Verfasst: Mittwoch 12. August 2009, 20:16
von Hyperion

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 ;-)

Verfasst: Mittwoch 12. August 2009, 20:37
von cofi
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.

Verfasst: Mittwoch 12. August 2009, 20:45
von AntagonisT
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.

Verfasst: Mittwoch 12. August 2009, 20:56
von AntagonisT
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'

Verfasst: Mittwoch 12. August 2009, 20:59
von cofi
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")

Verfasst: Mittwoch 12. August 2009, 21:02
von sma
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

Verfasst: Mittwoch 12. August 2009, 21:05
von AntagonisT
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...

Verfasst: Mittwoch 12. August 2009, 21:14
von cofi
``__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*

Verfasst: Mittwoch 12. August 2009, 21:16
von AntagonisT
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

Verfasst: Mittwoch 12. August 2009, 21:17
von AntagonisT
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...

Verfasst: Mittwoch 12. August 2009, 21:20
von Darii
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).

Verfasst: Mittwoch 12. August 2009, 21:25
von AntagonisT
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!

Verfasst: Donnerstag 13. August 2009, 03:42
von str1442