objekte direkte manipulation oder return

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
joliebig
User
Beiträge: 2
Registriert: Montag 9. Februar 2009, 17:24

Hi,
meine Frage dreht sich um eine allgemeingueltige Regel fuer das Verhalten von Objekten und deren zugehoerigen Methoden. In einigen Faellen werden Python-Objekte direkt durch Methoden manipuliert. So wuerde ich es auch erwarten. Ein Beispiel:

Code: Alles auswählen

a = [1, 2, 3]
a.append(4)
print(a)
Nutzt man hingegen die __add__ Funktion sieht es anders aus.

Code: Alles auswählen

a.__add__([5])
>> [1, 2, 3, 4, 5]
print(a)
[1, 2, 3, 4]
Aehnliches findet sich auch an anderen Stellen (bspw. Stringverarbeitung). Gibt es allgemeingueltige Regeln zum Verhalten von Objekten und deren Methoden zur Manipulation oder muss man das Verhalten kennen. Ich frage aus dem Grund, weil dieser Unterschied schon haeufig eine Fehlerquelle in meinen Programmen war.

Fuer Eure Muehe im voraus besten Dank
joliebig
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Gibt es eine Regel dafür?
Klares Ja
Wenn das Objekt verändert wird, gibt die Methode None zurück.

Ob ein Objekt verändert wird (oder werden kann) steht (hoffentlich) in der Doku (z.B. unicode/int/complex/tuple etc. sind "immutable", die kann man nicht verändern).


Und man kann oft aus dem Namen schließen, ob was verändert wird (append=>"anhängen", aber sorted=>"sortiert" nicht "sortier!").

Dein Beispiel mit "__add__" ist etwas irreführend, weil man "__add__" nie direkt benutzt, man nimmt "+":

Code: Alles auswählen

Python 2.5.1 Stackless 3.1b3 060516 #...
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2,3]
>>> a + [4,5]
[1, 2, 3, 4, 5]
>>> a
[1, 2, 3]
>>> a + 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list
Wenn sich da "a" verändern würde, wäre das etwas unerwartet(evtl. suchst du ja "+=" also "__iadd__").

hth, Jörg
edit: typos, überall typos
Zuletzt geändert von b.esser-wisser am Dienstag 24. Februar 2009, 10:50, insgesamt 1-mal geändert.
Wir haben schon 10% vom 21. Jahrhundert hinter uns!
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Das Verhalten ergibt sich sich daraus, was du machst. Mit append hängst du an eine vorhandene Liste ein Element an (dadurch bleibt die Liste natürlich gleich). Mit __add__ (was einfach dem "+"-Operator entspricht) fügst du zwei Listen zu einer neuen zusammen. Wenn du einfach nur eine andere Liste an die Liste anhängen willst, muss du list.extend benutzen.

Die Antwort auf deine Frage lautet also: Man muss das Verhalten kennen, meist wird das aber Objekt verändert. Bei Strings wird sowieso immer ein neues Objekt erstellt, da Strings unveränderlich sind.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

da hilft meist nur Doku lesen.

Zu deinem Beispiel:
append ist eine Methode und arbeitet auf der Instanz - fügt der Instanz also ein Element hinzu.

__add__ ist eine spezielle Methode, die automatisch aufgerufen wird, wenn du den +-Operator benutzt:

Code: Alles auswählen

l1 = [1, 2, 3]
l2 = [4, 5, 6]
l3 = l1 + l2
Hier wird eine dritte Liste erzeugt, mit den Elementen aus beiden Listen. Warum sollte hier die erste Liste geändert werden? Wenn du Listen zu einer Liste hinzufügen willst, dann gibt es die Methode extend (also wieder Doku lesen).

Gruß,
Manuel
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Immutable Objekte geben immer ein neues Objekt zurück, __underscore__ Methoden, welche einen Operator implementieren, geben immer ein neues Objekt zurück mit Ausnahme der "augmented" Operatoren. Das sind alle Operatoren mit einem "=": Für __add__ wäre das __iadd__ und entspricht +=, was das bei einer Liste das gleiche wie extend macht. Diese Methoden haben immer so ein vorangestellstes "i". Ist ein Objekt Mutable (veränderlich) und besitzt normale Methoden, die keinerlei speziellen Wert zurückgeben müssen (ala list.count, welches ja einen Integer zurück gibt), werden sie direkt auf das Objekt angewandt. Das ist die Regel. Man kann natürlich nicht generell davon ausgehen, da im Endeffekt der Programmierer die Macht hat, aber jede halbwegs gute Klasse sollte so agieren.
joliebig
User
Beiträge: 2
Registriert: Montag 9. Februar 2009, 17:24

Vielen Dank - Eure Antworten haben mir sehr geholfen Python wieder etwas besser zu verstehen.
Antworten