重複の可能性:
Pythonの「驚き最小の原則」:可変のデフォルト引数
次の2つの関数を検討してください
def a(var=[0]):
print (var)
var = var + [4]
def b(var=[0]):
print (var)
var.append(4)
それらは同じように動作する必要がありますが、さらに重要なことに、引数なしで呼び出された場合、両方とも単に「[0]」を出力する必要があります。動作は大きく異なり、a()のみが常に「[0]」を出力します。
>>> a()
[0]
>>> a()
[0]
>>> a()
[0]
>>> b()
[0]
>>> b()
[0, 4]
>>> b()
[0, 4, 4]
a()の機能がb()と異なるのはなぜですか?
関数に引数が渡されていない場合に変数をデフォルトで上書きしたい場合は、リストAPIを使用できないようです。そして、あなたがそうするならば、関数はそれが以前に変数であったものを「覚えている」でしょう。
私のコードの状況は再帰関数に現れるので、不要な変数を「削除」するだけでは実際には機能しません。引数なしで関数を呼び出すたびに変数を上書きする方法はありますか?
何時間もの研究の後で、私はこれを発見しました。上記の質問に関連している可能性があり、回答につながる可能性があります。次のようにライフタイムクラスを定義できます。
class lifetime: # adapted from http://naml.us/blog/tag/variable-lifetime
def __init__(self, name):
self.name = name
print ('creating: ' + name)
def __del__(self):
print ('destroying: ' + self.name)
def __iadd__(self, a):
self.append(a)
def append(self, a):
self.name += ' and ' + a.name
print('appending: ' + a.name + ' to ' + self.name)
次に、2つの関数を定義します。
def a(var=lifetime('a')):
print (var)
var += life('appendage')
def b(var=lifetime('b')):
print (var)
var.append(life('appendage'))
>>> a()
<__main__.lifetime object at 0x00000000031FFA90>
creating: appendage
appending: appendage to a and appendage
destroying: appendage
>>> a()
<__main__.lifetime object at 0x00000000031FFA90>
creating: appendage
appending: appendage to a and appendage and appendage
destroying: appendage
>>> b()
<__main__.lifetime object at 0x00000000031FFB38>
creating: appendage
appending: appendage to b and appendage
destroying: appendage
>>> b()
<__main__.lifetime object at 0x00000000031FFB38>
creating: appendage
appending: appendage to b and appendage and appendage
destroying: appendage
引数のデフォルトを一度評価してから、その評価が何であれ使用するようです。「作成中:a」または「作成中:b」とは決して言いません。したがって、デフォルトの引数を毎回評価すると、実際の質問に対する答えにつながる可能性があります。