[Python-de] Parameter in Python

Peter Otten __peter__ at web.de
Mi Nov 13 20:54:35 CET 2013


Marek Kubica wrote:

> On Tue, 12 Nov 2013 14:57:13 +0100
> Alexander Langer
> <alexander.langer at address.invalid> wrote:
> 
>> Am 12.11.2013 14:40, schrieb Christian Heimes:
>> > Spaß bei Seite, neue Pythonentwickler sind oft verwirrt, weil sie
>> > nur CBR und CBV in der Schule/Uni gelernt haben.
>> 
>> Das gilt auch für erfahrene Pythonentwickler.
> 
> Eigentlich nicht. Man muss sich halt bewusst machen das Neuzuweisung
> und Änderung eines Objektes zwei unterschiedliche Operationen sind, was
> jetzt nicht wirklich Raketenwissenschaft ist. Aber es gibt nen Trick,
> nämlich überall wo = steht ist das ne Zuweisung ;)
> 
> Das hat mit mutable und immutable erstmal gar nichts zu tun, weil ja
> bei sowas immer Äpfel und Birnen verglichen werden. Das
> Standardbeispiel wo Leute dann diese angebliche Inkonsistenz von Python
> festmachen wollen ist ja dieses:
> 
> a = 3
> def b(a)
>     a = 4
> b(a)
> print a
> 
> Wo sich nix ändert. Dann nimmt man ne Liste und
> 
> a = [1, 2, 3]
> def b(a)
>     a.append(4)
> b(a)
> print a
> 
> An dieser Stelle heißt dann "ohh, a hat sich geändert!". Ja natürlich,
> weil man ja das Objekt was an a gebunden ist geändert hat.
> 
> Wohingegen eine identische Übersetzung vom Zahlenbeispiel ja das hier
> ist:
> 
> a = [1, 2, 3]
> def b(a)
>     a = [4, 5, 6]
> b(a)
> print a
> 
> Da ändert sich natürlich auch nix, wozu auch? a ist an das gleiche
> Objekt gebunden wie davor auch und der neue lokale Name a in der
> Funktion ist ja von außen nicht sichtbar.

Das Prinzip ist einfach, es gibt allerdings fiese Beispiele, die geignet 
sind den Leser zu verwirren:

>>> def f(a, b):
...     a += b
...     print(a)
... 
>>> a = [1]
>>> f(a, [2])
[1, 2]
>>> a
[1, 2]
>>> a = 1,
>>> f(a, (2,))
(1, 2)
>>> a
(1,)

Die Erklärung ist natürlich, dass

a += b

zu

a = a.__iadd__(b)

aufgelöst wird, also sowohl einen Namen neu bindet als auch eine potentiell 
objektändernde Methode aufruft.

Und weil's so schön ist, gleich noch ein Klassiker:

>>> x = [], 2
>>> x[0] += "foo"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> x
(['f', 'o', 'o'], 2)




Mehr Informationen über die Mailingliste python-de