Marek Kubica wrote:
On Tue, 12 Nov 2013 14:57:13 +0100 Alexander Langer <alexander.langer@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)