デフォルト値を効果的に使用するには、デフォルト値がどのように機能するかを理解する必要があります。
関数はオブジェクトです。そのため、属性があります。したがって、この関数を作成すると:
>>> def f(x, y=[]):
y.append(x)
return y
オブジェクトを作成しました。その属性は次のとおりです。
>>> dir(f)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__',
'__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__',
'__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals',
'func_name']
それらの1つはですfunc_defaults
。それは有望に聞こえますが、そこには何がありますか?
>>> f.func_defaults
([],)
これは、関数のデフォルト値を含むタプルです。デフォルト値がオブジェクトの場合、タプルにはそのオブジェクトのインスタンスが含まれます。
f
これは、リストに項目を追加し、リストが提供されていない場合にその項目のみを含むリストを返すことを考えている場合、かなり直感に反する動作につながります。
>>> f(1)
[1]
>>> f(2)
[1, 2]
しかし、デフォルト値が関数の属性の 1 つに格納されているオブジェクト インスタンスであることがわかっている場合は、それほど直感的ではありません。
>>> x = f(3)
>>> y = f(4)
>>> x == y
True
>>> x
[1, 2, 3, 4]
>>> x.append(5)
>>> f(6)
[1, 2, 3, 4, 5, 6]
これを知っていれば、関数のパラメーターのデフォルト値を新しいリスト (または任意の新しいオブジェクト) にしたい場合、単純にオブジェクトのインスタンスを に隠しておくことはできないことは明らかですfunc_defaults
。関数が呼び出されるたびに新しいものを作成する必要があります。
>>>def g(x, y=None):
if y==None:
y = []
y.append(x)
return y