
I have added python-ideas to the Cc list, and suggest removing python-3000 from additional replies. BJörn Lindqvist gave an example explaining why he might want to re-evaluate mutable default arguments. It still looks like like buggy code, but it isn't the error I was expecting -- and I think it comes from the difficulty of declaring something immutable. On 2/15/07, BJörn Lindqvist <bjourne@gmail.com> wrote:
On 2/15/07, Jim Jewett <jimjjewett@gmail.com> wrote:
Then are there *any* good use cases for [non-persistent mutable defaults]
(1) Not really (treated as) mutable. ==> Doesn't care
>>> def f(extra_settings={}) ...
usually doesn't modify or even store extra_settings; ...
That is dangerous code. Sooner or later someone will modify the extra_settings dict.
How? >>> f.func_defaults[0]['key']=value may be misguided, but it probably isn't an accident. BJörn's example does store the mutable directly, but it makes a bit more sense because it looks like a complex object rather than just a mapping.
class Vector: def __init__(self, x, y, z): self.x = x self.y = y self.z = z
class Ray: def __init__(self, direction, origin = Vector(0, 0, 0)): self.direction = direction self.origin = origin
ray1 = Ray(Vector(0, 0, -1)) ray2 = Ray(Vector(0, 0, 1)) ray3 = Ray(Vector(-1, 0, 0), Vector(2, 3, 4))
The above code looks quite nice, but is wrong.
Why is vector mutable? Is the real problem that it is too hard to declare objects or attributes immutable? My solution is below, but I'll grant that it isn't as straightforward as I would have liked. Is this something that could be solved with a recipe, or a factory to make immutable classes?
class Vector3D(tuple): ... def __new__(self, x, y, z): ... return super(Vector3D, self).__new__(self, (x, y, z)) ... x=property(lambda self: self[0]) ... y=property(lambda self: self[1]) ... z=property(lambda self: self[2])
-jJ