Pythonでは関数の引数にデフォルト値を設定することが可能です。ただし、リストや辞書のような変更可能なオブジェクト、または関数をデフォルト引数として使用する場合は、注意が必要です。
以下のコードでは、1秒おきにUNIX時間が表示されるはずですが、実際には同じ数字が3回表示されます。これは、n=time.time()
という引数が、関数が定義された時に一度だけ評価されるためです。そのため、表示される3つの数字はすべて、関数が定義された瞬間の時刻となります。
import time
def printer(n=time.time()):
print(n)
for _ in range(3):
printer()
time.sleep(1)
# 出力:同じ数字3つが表示された
公式ドキュメントによれば、
デフォルト引数値は関数定義が実行されるときに左から右へ評価されます。 これは、デフォルト引数の式は関数が定義されるときにただ一度だけ評価され、同じ "計算済みの" 値が呼び出しのたびに使用されることを意味します。(中略)このような動作を避けるには、デフォルト値として None を使い、この値を関数本体の中で明示的にテストします。
とされており、前述のコードを修正するのであれば、以下が適切なコードとなります。
def printer(n=None):
if n is None:
n = time.time()
print(n)
ちょっとしたプログラムであれば問題ありませんが、Webアプリなどを構築する場合、サーバーが起動した時刻で計算され続ける可能性があり、注意が必要ですね。(まんまと引っ掛かりました)