Issue with function keyword defaults
Ken Seehof
kseehof at neuralintegrator.com
Sun Aug 5 08:36:38 EDT 2001
The default expression "{}" is evaluated only once, when the function
is defined. The value of the expression is stored as a property of the
function object. Thus the binding for r doesn't change, but it's value
is a dictionary, which is mutable.
The moral of the story is: mutable default arguments are dangerous.
Actually, mutable arguments in general are dangerous, unless you
know how they work.
What you need to do is this:
>>> def test(r={}):
... r = r.copy()
... r[time.time()] = time.time()
... return r
...
>>> test()
{997013843.75999999: 997013843.75999999}
>>> test()
{997013845.57000005: 997013845.57000005}
>>> test()
{997013846.88999999: 997013846.88999999}
Note that the copy also protects your dictionary argument from
side effects if one is passed in. In the original version you get:
>>> def test(r={}):
... r[time.time()] = time.time()
... return r
...
>>> z = {'a':1}
>>> test(z)
{997014161.34000003: 997014161.34000003, 'a': 1}
>>> z
{997014161.34000003: 997014161.34000003, 'a': 1}
This may or may not be what you want, but "functional programming"
monks consider such things to be sacrilegious. In fact, your example
should give functional programming monks a good reason to go find a
different language! :-)
- Ken Seehof
kseehof at neuralintegrator.com
www.neuralintegrator.com/kseehof
From: "Morten W. Petersen" <morten at thingamy.net>
> Hi,
>
> after trying to set an empty dictionary as a default keyword arguments'
> value, this happened (same thing happened on 2.0.1 BTW):
>
> morten at debian:~$ python
> Python 1.5.2 (#0, Apr 10 2001, 10:03:44) [GCC 2.95.3 20010219
> (prerelease)] on linux2 Copyright 1991-1995 Stichting Mathematisch
> Centrum, Amsterdam
> >>> import time
> >>> def test(r={}):
> ... r[time.time()] = time.time()
> ... return r
> ...
> >>> test()
> {997015577.922: 997015577.922}
> >>> test()
> {997015578.849: 997015578.849, 997015577.922: 997015577.922}
> >>> test()
> {997015579.446: 997015579.446, 997015578.849: 997015578.849,
> 997015577.922: 997015577.922
>
> I would assume that r would be re-initialized on every call, but that's
> not happening; could anyone explain this behaviour?
>
> Thanks,
>
> Morten
>
> --
> http://mail.python.org/mailman/listinfo/python-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20010805/f4c1f5f4/attachment.html>
More information about the Python-list
mailing list