【Python】関数のデフォルト引数の書き方

この記事では、Pythonの関数におけるデフォルト引数の書き方と注意点、そしてデフォルト引数の利用例について解説します。

デフォルト引数を使うことで、関数の柔軟性や再利用性を高めることができます。

また、デフォルト引数の値が共有される問題や、ミュータブルなオブジェクトをデフォルト引数に指定する場合の注意点も解説していきます。

目次から探す

デフォルト引数とは

関数を定義する際に、引数にデフォルトの値を設定することができます。

デフォルト引数を使用することで、引数が指定されなかった場合にはデフォルトの値が使用されます。

デフォルト引数の書き方

基本的な書き方

デフォルト引数を指定するには、関数の引数の後ろにイコール(=)を使ってデフォルトの値を指定します。

例えば、以下のような関数を考えてみましょう。

def greet(name="World"):
    print("Hello, " + name + "!")

この場合、nameという引数にデフォルトの値として”World”を指定しています。

引数が指定されなかった場合には、"World"が使用されます。

複数のデフォルト引数の指定

関数には複数の引数を持たせることもできます。

複数の引数にデフォルトの値を指定する場合には、引数の順番に注意が必要です。

デフォルト引数を持つ引数は、必ず後ろに配置する必要があります。

例えば、以下のような関数を考えてみましょう。

def greet(name="World", greeting="Hello"):
    print(greeting + ", " + name + "!")

この場合、nameとgreetingという2つの引数にデフォルトの値を指定しています。

引数が指定されなかった場合には、nameには”World”、greetingには"Hello"が使用されます。

デフォルト引数の値の変更

デフォルト引数の値は、関数内で変更することもできます。

例えば、以下のような関数を考えてみましょう。

def greet(name="World"):
    name = name.capitalize()
    print("Hello, " + name + "!")

この場合、nameのデフォルトの値は”World”ですが、関数内でname.capitalize()を使って名前の先頭を大文字に変換しています。

つまり、引数が指定されなかった場合には"World"が使用されますが、引数が指定された場合には、その値が大文字に変換された上で使用されます。

デフォルト引数の注意点

デフォルト引数の値が共有される問題

デフォルト引数の値は、関数が定義された時点で一度だけ評価されます。

そのため、デフォルト引数がミュータブルなオブジェクト(リストや辞書など)である場合、関数が複数回呼び出された際に予期しない結果が生じることがあります。

例えば、以下のような関数を考えてみましょう。

def add_item(item, items=[]):
    items.append(item)
    print(items)

この関数は、itemitemsというリストに追加して、その内容を表示するものです。

しかし、この関数を複数回呼び出すと、予期しない結果が生じます。

add_item("apple")  # ['apple']
add_item("banana")  # ['apple', 'banana']
add_item("orange")  # ['apple', 'banana', 'orange']

このように、最初の呼び出しでは['apple']が表示されますが、2回目の呼び出しでは[‘apple’, ‘banana’]、3回目の呼び出しでは['apple', 'banana', 'orange']となります。

これは、デフォルト引数のリストが関数が定義された時点で一度だけ評価され、その後の呼び出しで共有されるためです。

この問題を回避するためには、デフォルト引数としてミュータブルなオブジェクトを使用する場合には、関数内で新しいオブジェクトを作成するようにする必要があります。

ミュータブルなオブジェクトをデフォルト引数に指定する場合の注意点

デフォルト引数にミュータブルなオブジェクト(リストや辞書など)を指定する場合には、注意が必要です。

ミュータブルなオブジェクトは関数が呼び出されるたびに変更される可能性があるため、予期しない結果が生じることがあります。

例えば、以下のような関数を考えてみましょう。

def add_item(item, items=[]):
    items.append(item)
    print(items)

この関数は、itemitemsというリストに追加して、その内容を表示するものです。

しかし、この関数を複数回呼び出すと、予期しない結果が生じます。

add_item("apple")  # ['apple']
add_item("banana")  # ['apple', 'banana']
add_item("orange")  # ['apple', 'banana', 'orange']

このように、最初の呼び出しでは['apple']が表示されますが、2回目の呼び出しでは[‘apple’, ‘banana’]、3回目の呼び出しでは['apple', 'banana', 'orange']となります。

これは、デフォルト引数のリストが関数が定義された時点で一度だけ評価され、その後の呼び出しで共有されるためです。

この問題を回避するためには、デフォルト引数としてミュータブルなオブジェクトを使用する場合には、関数内で新しいオブジェクトを作成するようにする必要があります。

デフォルト引数の利用例

デフォルト引数を使ったオプションの指定

関数の引数にデフォルトの値を指定することで、オプションの指定が簡単になります。

例えば、以下のような関数を考えてみましょう。

def greet(name="World", greeting="Hello"):
    print(greeting + ", " + name + "!")

この関数では、nameとgreetingという2つの引数にデフォルトの値を指定しています。

引数を指定しなかった場合には、nameには”World”、greetingには"Hello"が使用されます。

しかし、必要に応じて引数を指定することもできます。

greet()  # Hello, World!
greet("Alice")  # Hello, Alice!
greet("Bob", "Hi")  # Hi, Bob!

このように、デフォルト引数を使うことで、オプションの指定が柔軟になります。

デフォルト引数を使った初期化処理

デフォルト引数を使うことで、関数内での初期化処理を簡単に行うことができます。

例えば、以下のような関数を考えてみましょう。

def initialize_list(items=[]):
    items.clear()
    print(items)

この関数では、itemsというリストを初期化して、その内容を表示します。

デフォルト引数として空のリストを指定しているため、引数が指定されなかった場合には空のリストが使用されます。

initialize_list()  # []
initialize_list([1, 2, 3])  # []

このように、デフォルト引数を使うことで、関数内での初期化処理を簡潔に記述することができます。

デフォルト引数を使った再帰関数の実装

デフォルト引数を使うことで、再帰関数の実装が容易になります。

再帰関数は、自身の関数を呼び出すことで処理を繰り返す関数です。

例えば、以下のような再帰関数を考えてみましょう。

def countdown(n=10):
    if n == 0:
        print("Blastoff!")
    else:
        print(n)
        countdown(n-1)

この関数は、引数として指定された数からカウントダウンを行い、0になったら"Blastoff!"と表示します。

デフォルト引数として10を指定しているため、引数が指定されなかった場合には10からカウントダウンが始まります。

countdown()  # 10 9 8 7 6 5 4 3 2 1 Blastoff!
countdown(5)  # 5 4 3 2 1 Blastoff!

このように、デフォルト引数を使うことで、再帰関数の実装が簡単になります。

以上が、関数のデフォルト引数の書き方です。

デフォルト引数を使うことで、関数の柔軟性や再利用性を高めることができます。

ただし、デフォルト引数の値が共有される問題や、ミュータブルなオブジェクトをデフォルト引数に指定する場合の注意点にも注意しながら、適切に利用してください。

目次から探す