[Python-ideas] my take on mutable default arguments
Gabriel Genellina
gagsl-py at yahoo.com.ar
Sun Jan 28 01:42:37 CET 2007
"tomer filiba" <tomerfiliba at gmail.com>
escribió en el mensaje
news:1d85506f0701271422j5650fcdajefb0ab33215c1de3 at mail.gmail.com...
> On 1/28/07, Chris Rebert
> <cvrebert at gmail.com> wrote:
>> As pointed out by Calvin Spealman in an earlier email:
>>
>> Calvin Spealman wrote:
>> > Deep copy of the originally created
>> > default argument can be expensive and would not work in any useful way
>> > with non-literals as defaults, such as function calls or subscript
>> > lookups or even simple attributes.
>
> first, please refer to my second version (@copydefaults).
>
> second, theoretically all objects are copyable, as long as they
> define __copy__ or __deepcopy__. it's up to you.
No, I think he's pointing another problem. For function calls, subscripts or
attributes, it's important *when* you execute it. By example:
def foo1(x, prompt=sys.ps2):
print prompt,x
def foo2(x, prompt=None):
if prompt is None: prompt=sys.ps2
print prompt,x
@copydefaults
def foo3(x, prompt=sys.ps2):
print prompt,x
If the intent of the author is "use sys.ps2 unless I pass an explicit
prompt" neither foo1 nor foo3 will work if sys.ps2 is changed.
> second, theoretically all objects are copyable, as long as they
> define __copy__ or __deepcopy__. it's up to you.
Not all objects are copyable, or not as one would expect:
@copydefaults
def foo4(x, outfile=sys.stdout):
"Use sys.stdout unless an explicit outfile is given"
outfile.write(x)
foo4 doesn't even work, it raises: ValueError: I/O operation on closed file.
Even if you manage to special-case files, or "fix" how they are copied, it
won't work as intended because sys.stdout could have been reassigned after
the function was defined.
So you have to use the old idiom anyway:
def foo5(x, outfile=None):
if outfile is None: outfile = sys.stdout
outfile.write(x)
> third, you'll use this decorator only when you want "fresh copies" of the
> default values... not "just for fun", [...]
Some way to say "I want this default argument to be re-evaluated when I
don't provide an explicit value" would be useful, but this proposal does not
help on this.
--
Gabriel Genellina
More information about the Python-ideas
mailing list