Richtig.HerrHagen hat geschrieben:Das Problem mit der Geschichte ist, dass der Umstand, dass ein default-Argument nur einmalig erzeugt wird, vielen nicht bekannt,bords0 hat geschrieben:Deshalb halte ich es für etwas klarer, das Problem nicht auf die mutablen Default-Argumente zu schieben, sondern auf das Mutieren selbst.
Eigentlich nur, bis man verstanden hat, dass das "def"-Statement tatsächlich ausgeführt wird - und zwar zur Definition der Funktion, nicht beim Aufruf derselben.überdies auch sehr unintuitiv,
Da sind wir überhaupt nicht einer Meinung... weil es IMO keine sinnvollere Alternative gibt.und IMO auch ziemlich unsinnig ist.
Das ist m.E. zwar i.W. richtig, aber es gibt Ausnahmen.Um solche Probleme wie oben gesehen zu vermieden, sollte man auf solche Sachen von vornherein verzichten. Wenn das Objekt also sowieso nicht verändert werden sollte, dann sollte dies auch durch die Datenstruktur entsprechend abgebildet werden (also unveränderliche Liste = tuple).
Code: Alles auswählen
>>> def shuffled_range(n, extra=[]):
import random
r = range(n) + extra
random.shuffle(r)
return r
>>> shuffled_range(5)
[2, 0, 4, 3, 1]
>>> shuffled_range(10, [-1, "Zehn"])
['Zehn', 9, 6, -1, 5, 0, 8, 3, 7, 1, 4, 2]
>>> shuffled_range(5, ())
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
shuffled_range(5, ())
File "<pyshell#5>", line 3, in shuffled_range
r = range(n) + extra
TypeError: can only concatenate list (not "tuple") to list
Code: Alles auswählen
>>> class Spam(object):
def __init__(self, attrs={}):
self.__dict__.update(attrs)
>>> s = Spam()
>>> s.__dict__
{}
>>> t = Spam({"foo": "bar", "baz": "blubb"})
>>> t.__dict__
{'foo': 'bar', 'baz': 'blubb'}
>>> t.baz
'blubb'