Python=で、関数の引数のデフォルト値として可変オブジェクトを設定するのはよくある間違いです。これは から取られた例です。デビッド・グッドガー :
>>> 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']
これが発生する理由は、 こちら です。
そして今私の質問のために:この構文の良いユースケースはありますか?
つまり、それに遭遇したすべての人が同じ間違いを犯し、それをデバッグし、問題を理解し、そこからそれを回避しようとすると、そのような構文にはどのような用途がありますか?
これを使用して、関数呼び出し間の値をキャッシュできます。
def get_from_cache(name, cache={}):
if name in cache: return cache[name]
cache[name] = result = expensive_calculation()
return result
しかし、通常、そのようなことは、キャッシュをクリアするための追加の属性を持つことができるので、クラスを使用することでよりうまく行われます。
import random
def ten_random_numbers(rng=random):
return [rng.random() for i in xrange(10)]
random
モジュールを使用して、事実上可変のシングルトンをデフォルトの乱数ジェネレーターとして使用します。
多分あなたは変更可能な引数を変更しませんが、変更可能な引数を期待します:
_def foo(x, y, config={}):
my_config = {'debug': True, 'verbose': False}
my_config.update(config)
return bar(x, my_config) + baz(y, my_config)
_
(はい、私はあなたがこの特定の場合にconfig=()
を使用できることを知っていますが、あまり明確でなく、一般的ではないことがわかります。)
標準的な答えはこのページです: http://effbot.org/zone/default-values.htm
また、可変デフォルト引数の3つの「良い」使用例についても触れています。
編集(説明):変更可能なデフォルト引数の問題は、より深い設計の選択の症状です。つまり、デフォルト引数の値は、関数オブジェクトの属性として格納されます。この選択が行われた理由を尋ねるかもしれません。いつものように、そのような質問は適切に答えることが困難です。しかし、それは確かに良い用途を持っています:
パフォーマンスの最適化:
def foo(sin=math.sin): ...
変数の代わりにクロージャーでオブジェクト値を取得します。
callbacks = []
for i in range(10):
def callback(i=i): ...
callbacks.append(callback)