関数

関数の引数 の Python

{other: "%{count}個の演習"}

関数の引数について

関数の引数の基本については、関数の概念を参照してください。

仮引数の名前

仮引数の名前は、変数の名前と同じように、文字かアンダースコアで始まる必要があり、文字、アンダースコア、数字を含めることができます。 仮引数の名前には、空白や句読点を含めることはできません。

位置引数

位置引数は、それに対応する仮引数と同じ順序で関数に渡される値です。 位置引数は、その仮引数の名前を使って渡すこともできます:

def concat(greeting, name):
    return f"{greeting}{name}"

# Passing data to the function by position.
print(concat("Hello, ", "Lilly"))
#->  Hello, Lilly

# Passing data to the function using the parameter name.
print(concat(name="Glenn", greeting="Hello, "))
#-> Hello, Glenn

最初のconcatの呼び出しでは、引数を位置で渡しています。 2回目のconcatの呼び出しでは、引数を名前で渡しているので、位置を入れ替えることができます。

なお、名前で渡した引数(_これはキーワード引数とも呼ばれます。可変位置引数や**kwargsと混同しないでください)。_の後ろには、位置引数を置くことはできません。

次の引数の組み合わせを見てください:

print(concat(greeting="Hello, ", "Gregor"))

これは次のエラーになります:

SyntaxError: positional argument follows keyword argument

関数呼び出しで位置専用引数を必須にするには、仮引数リストで/演算子を使います:

# Parameters showing a position-only operator. 
def concat(greeting, name, /):
    return f"{greeting}{name}"

print(concat("Hello, ", "Ginnie"))
#-> Hello, Ginnie

# Call to the function using keyword arguments.
print(concat(name="Franklin", greeting="Hello, "))
Traceback (most recent call last):
    print(concat(name="Franklin", greeting="Hello, "))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'

キーワード引数

キーワード引数は、関数を呼び出すときに仮引数の名前を使います。 位置で指定することもできます:

def concat(greeting, name):
    return f"{greeting}{name}"

# Function call using parameter names as argument keywords.
print(concat(name="Eliza", greeting="Hello, "))
#-> Hello, Eliza

# Function call with positional data as arguments.
print(concat("Hello, ", "Tim"))
#-> Hello, Tim

関数呼び出しでキーワード専用引数を必須にするには、仮引数リストで*演算子を使います:

# Function definition requiring keyword-only arguments.
def concat(*, greeting, name):
    return f"{greeting}{name}"

# Keyword arguments can be in an arbitrary order.
print(concat(name="Kimmie", greeting="Hello, "))
#-> Hello, Kimmie

# Calling the function with positional data raises an error.
print(concat("Hello, ", "Coleen"))
Traceback (most recent call last):
    print(concat("Hello, ", "Coleen"))
TypeError: concat() takes 0 positional arguments but 2 were given

デフォルト引数の値

仮引数リストには、1つ以上の引数のデフォルト値を指定できます。 これにより、必要に応じて_より少ない_引数で関数を呼び出せるようになります。 デフォルト値は、新しい引数の値を渡して関数を呼び出すことで上書きでき、デフォルトは置き換わります:

# Function with default argument values.
def concat(greeting, name="you", punctuation="!"):
    return f"{greeting}, {name}{punctuation}"

print(concat("Hello"))
#-> Hello, you!

# Overriding the default values
print(concat("Hello", name="Polly", punctuation="."))
#-> Hello, Polly.

位置引数またはキーワード引数

仮引数の定義で/演算子も*演算子も使っていなければ、引数は位置でもキーワードでも渡せます。 または、位置でもキーワードでも渡せる引数を、左側の位置専用の仮引数と右側のキーワード専用の仮引数の間に置くこともできます:

# Position-only argument followed by position-or-keyword, followed by keyword-only.
def concat(greeting, /, name, *, ending):
    return f"{greeting}{name}{ending}"

print(concat("Hello, ", "Mark", ending="!"))
#-> Hello, Mark!

print(concat("Hello, ", name="Rachel", ending="!"))
#-> Hello, Rachel!

print(concat(greeting="Hello, ", name="JoJo", ending="!"))
Traceback (most recent call last):
    print(concat(greeting="Hello, ", name="JoJo", ending="!"))
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'

*args

コード例では、よく次のような関数定義が使われます:

def my_function(*args, **kwargs):
    # code snipped

*argsは、2つの部分からなる名前で、個数が決まっていない複数の位置引数からなるtupleを表します。これはvariadic argumentとも呼ばれます。 argsは、引数のtupleに付けられた名前ですが、my_argsやargumentsなど、有効なPythonの名前であれば何でもかまいません。 *は、個々の引数のまとまりをtupleに変換する演算子です。

Note

これまでにタプルをアンパックしたことがあれば、*argsの*に戸惑うかもしれません。 _仮引数_の定義における*は、タプルをアンパックするのではなく、1つ以上の位置引数を_タプルに_変換します。

*演算子はオーバーロードされていると言えます。文脈によって振る舞いが異なるからです。 たとえば、*は掛け算に使われ、アンパックに使われ、任意の個数の位置引数を定義するのにも使われます。

tupleは繰り返し処理できるので、argsはイテラブルを受け取る他のどんな関数にも渡せます。 *argsは**kwargsと並べて使われることが多いですが、必ずしもそうする必要はありません:

def add(*args):
    # args is passed to the sum function, which iterates over it.
    return sum(args)

print(add(1, 2, 3))
#-> 6

*argsが1つ以上の位置引数の後ろに続く場合、*argsには位置引数の後ろに残った値が入ります:

def add(first, *args):
    # first will be 1, leaving the values 2 and 3 in *args
    return first + sum(args)

print(add(1, 2, 3))
#-> 6

*argsの後ろに1つ以上のデフォルト引数を定義すると、それらは*argsの値とは別になります:


def add(first, *args, last=0):
    return first + sum(args) + last
 
print(add(1, 2, 3))
#-> 6

print(add(1, 2, 3, last=4))
#-> 10

# This uses the unpacking operator * to separate the list elements into positional arguments.
# It does not have the same behavior as the * (packing) in *args.
print(add(*[1, 2, 3]))
#-> 6

引数がすでにiterable(tupleやlistなど)の中にある場合は、任意の個数の個別の引数を受け取る関数に渡す前に、アンパックする必要があります。 これは*を使うことで実現でき、*はアンパック演算子です。

この文脈での*は、コンテナを個々の要素に_アンパック_し、それらの要素は*argsによってtupleに変換されます。 位置引数だけを使う場合は、アンパックした結果が、定義されている仮引数と同じ数の引数にならなければなりません。

addに渡したリストをアンパックしないと、プログラムはエラーになります:

def add(first, *args, last=0):
    return first + sum(args) + last

print(add([1, 2, 3]))
Traceback (most recent call last):
    print(add([1, 2, 3]))
    return first + sum(args) + last
TypeError: can only concatenate list (not "int") to list

**kwargs

**kwargsは、2つの部分からなる名前で、個数が決まっていない複数のキーと値のペアの引数を表します。 kwargsはその引数のまとまりに付けられた名前で、my_argsやargumentsなど、他の名前でもかまいません。 **は、名前付き引数のまとまりを、{argument name: argument value}のペアからなるdictionaryに変換します。

辞書も繰り返し処理できるので、kwargsはイテラブルを受け取る他のどんな関数にも渡せます。 **kwargsは*argsと並べて使われることが多いですが、必ずしもそうする必要はありません:

def add(**kwargs):
    return sum(kwargs.values())

print(add(one=1, two=2, three=3))
#-> 6

kwargs辞書のvaluesを繰り返し処理するために、dict.values()メソッドが呼び出されている点に注意してください。 辞書を繰り返し処理するとき、デフォルトでは_keys_が対象になるので、dict.values()を明示的に指定する必要があります:

def concat(**kwargs):
    # Join concatenates the tuples from `kwargs.items()`
    return " ".join((str(item) for item in kwargs.items()))

print(concat(one=1, two=2, three=3))
#-> ('one', 1) ('two', 2) ('three', 3)
GitHubで編集 リンクは新しいウィンドウまたはタブで開きます