Python

Python 関数のデフォルト引数と注意

関数のデフォルト引数とは

シンプルな関数で確認する。

def f(x, y):
    print(x, y) 

f(0, 1) #0 1

何度も使う関数で、引数を省略したい場合は以下のようにするとデフォルトを設定できる。第2引数を設定しない場合も宣言、代入され使用できる。

def f(x, y = 42):
    print(x, y) 

# 第1引数は必須、第2引数(オプション)はデフォルトを使用
f(0) #0 42

# デフォルト引数を2つとも設定する場合は以下のようになる
def f2(x = 0, y = 42):
    print(x, y) 

f2() # 0 42

# 第1引数のみ設定すると、第2引数はデフォルトを使用
f2(99) # 99 42

# 第1引数はデフォルト、第2引数はデフォルト引数を上書く
f2(y = -1) # 0 -1

関数のデフォルト引数の注意

引数は、作成後に値(状態)の更新ができない変数(イミュータブル)にしないと期待と異なる結果になることがある。具体例を示す。

def f(x, args=[]):

    args.append(x)
    return args
 
print(f(0)) # [0]
print(f(42)) # [0, 42]
print(f(-1)) # [0, 42, -1]

示された通り、デフォルト引数に配列を設定し内部でappend()した場合、配列に値が追加され続ける挙動となる。これはデフォルトの引数の評価が初めの1度のみであるためである。

以下のように内部でデフォルト引数が設定されたかを判定することで回避できる。

def f_fix(x, args=None):

    if args is None:
        args = []
 
    args.append(x)
    return args
 
print(f_fix(0)) # [0]
print(f_fix(42)) # [42]
print(f_fix(-1)) # [-1]