[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