Good uses for mutable function argument default values?

时间秒杀一切 提交于 2019-12-28 04:59:09

问题


It is a common mistake in Python to set a mutable object as the default value of an argument in a function. Here's an example taken from this excellent write-up by David Goodger:

>>> def bad_append(new_item, a_list=[]):
        a_list.append(new_item)
        return a_list
>>> print bad_append('one')
['one']
>>> print bad_append('two')
['one', 'two']

The explanation why this happens is here.

And now for my question: Is there a good use-case for this syntax?

I mean, if everybody who encounters it makes the same mistake, debugs it, understands the issue and from thereon tries to avoid it, what use is there for such syntax?


回答1:


You can use it to cache values between function calls:

def get_from_cache(name, cache={}):
    if name in cache: return cache[name]
    cache[name] = result = expensive_calculation()
    return result

but usually that sort of thing is done better with a class as you can then have additional attributes to clear the cache etc.




回答2:


Maybe you do not mutate the mutable argument, but do expect a mutable argument:

def foo(x, y, config={}):
    my_config = {'debug': True, 'verbose': False}
    my_config.update(config)
    return bar(x, my_config) + baz(y, my_config)

(Yes, I know you can use config=() in this particular case, but I find that less clear and less general.)




回答3:


import random

def ten_random_numbers(rng=random):
    return [rng.random() for i in xrange(10)]

Uses the random module, effectively a mutable singleton, as its default random number generator.




回答4:


Canonical answer is this page: http://effbot.org/zone/default-values.htm

It also mentions 3 "good" use cases for mutable default argument:

  • binding local variable to current value of outer variable in a callback
  • cache/memoization
  • local rebinding of global names (for highly optimized code)



回答5:


EDIT (clarification): The mutable default argument issue is a symptom of a deeper design choice, namely, that default argument values are stored as attributes on the function object. You might ask why this choice was made; as always, such questions are difficult to answer properly. But it certainly has good uses:

Optimising for performance:

def foo(sin=math.sin): ...

Grabbing object values in a closure instead of the variable.

callbacks = []
for i in range(10):
    def callback(i=i): ...
    callbacks.append(callback)


来源:https://stackoverflow.com/questions/9158294/good-uses-for-mutable-function-argument-default-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!