Python PR

【Python】特殊な引数の使い方【デフォルト引数・位置専用引数・キーワード専用引数・任意引数リスト】

記事内に商品プロモーションを含む場合があります

この記事では、Pythonの引数の使い方を解説します。

引数を使うことで関数内やメソッド内で使用する値を外部から受け取ることができます。また、デフォルト値を設定したり位置専用にしたり色々なオプションが用意されています。

関数の使い方は以下の記事を参照してください。

【Python】関数の定義と呼び出しかた【def文】この記事では、Pythonの関数の定義と使い方を解説します。関数とは、コードをグループ化して名前を付けたものです。関数を定義することで、付けた名前からグループ化した処理を何度も呼び出すことができ、コードの重複を避けることができます。...

それでは、引数の使い方を見ていきましょう!

引数の基本

引数は以下のように定義します。

def 関数名(引数1, 引数2, ..., 引数N):

関数定義時に使用する引数のことを「仮引数(parameter)」、関数呼び出し時に引き渡される値のことを「実引数(argument)」と呼ぶ

アノテーションで型を指定することもできる。

def func(arg1: int, arg2: str):

型ヒントで使用する型を指定しよう【アノテーション】

サンプル

引数で外部から値を受け取って出力してみます。

def intro(name: str, age: int):
    print(f'名前: {name}, 年齢: {age}')


intro('田中太郎', 20)

実行結果

名前: 田中太郎, 年齢: 20

デフォルト値の指定

仮引数に=で繋いで値を指定することでデフォルト値を定義することができます。

def func(arg: int = 1):

引数が複数ある場合、前の引数にだけ初期値を付けることはできない。以下のコードでは、SyntaxErrorが発生する。

def func(name: str = 'noname', age: int):

後ろから前に付けることは可能です。

def func(name: str, age: int = 0):
def func(name: str = 'noname', age: int = 0):

デフォルト値を指定した引数は呼び出し時に省略することもできます。

def func(name: str = 'noname', age: int = 0):
    print(f'name: {name}, age: {age}')

# 第二引数を省略
func('Mike')
# 第一引数を省略
func(age=20)
# 引数を省略
func()

実行結果

name: Mike, age: 0
name: noname, age: 20
name: noname, age: 0

ただし、デフォルト値を指定する際に注意しなければならないのがミュータブルなオブジェクトを使用する場合です。

デフォルト値は、関数が定義されたときに一度だけ生成されます。つまりは同じオブジェクトを使い回していることになります。

そうするとミュータブルなオブジェクトでは、前回の変更がそのまま残ってしまっているのでめちゃくちゃ使いづらいです。例えば、以下のような感じですね。

def func(datas: list = []):
    datas.append(1)
    print(datas)

func()
func()

実行結果

[1]
[1, 1]

ミュータブルなオブジェクトにデフォルト値を指定したい場合は、Noneを用いるのが一般的です。例えば、以下のような感じです。

def func(datas: list = None):
    if datas is None:
        datas = [] 
    datas.append(1)
    print(datas)

func()
func()

実行結果

[1]
[1]

位置専用引数

仮引数として/(スラッシュ)を記述するとそれよりも前の仮引数は全て位置専用引数となります。

def 関数名(引数, /):
    なんらかの処理

サンプル

位置専用引数を定義した関数を「通常の呼び出し」と「キーワード呼び出し」で使ってみます。

def func(arg, /):
    print(arg)

func(0)
func(arg=0)

実行結果

0
Traceback (most recent call last):
  File "main.py", line 8, in <module>
    func(arg=0)
TypeError: func() got some positional-only arguments passed as keyword arguments: 'arg'

使い所

辞書の可変長引数を受け取る関数でkeyと引数名が被ってしまった場合に、名前の衝突を避けることができます。

例えば以下のコードを見てください。

def func(name, **kwds):
    print(name, kwds['name'])

person = {'name': 'Mike'}
func('John', **person)

このコードを実行するとname引数に複数の値が渡されTypeErrorが発生します。しかし、以下のように位置専用引数にすることでこのエラーは回避できます。

# nameを位置専用に
def func(name, /, **kwds):
    print(name, kwds['name'])

person = {'name': 'Mike'}
func('John', **person)

キーワード専用引数

仮引数として*(アスタリスク)を記述するとそれよりも後ろの仮引数は全てキーワード専用引数となります。

def 関数名(*, arg):
    なんらかの処理

サンプル

キーワード専用引数を定義した関数を「通常の呼び出し」と「キーワード呼び出し」で使ってみる。

def func(*, arg):
    print(arg)

func(arg=0)
func(0)

実行結果

0
Traceback (most recent call last):
  File "main.py", line 8, in <module>
    func(0)
TypeError: func() takes 0 positional arguments but 1 was given

位置専用 + キーワード専用

1つの関数に位置専用とキーワード専用の引数を定義することができます。

def 関数名(位置専用, ..., /, 通常, ..., *, キーワード専用, ...):
    なんらかの処理

サンプル

試しにどちらの引数も定義した関数を呼び出してみます。

def func(pos, /, nor, *, key):
    print(pos, nor, key)

func('pos', 'nor', key='key')

# もちろんnor引数はキーワード呼び出しもできる
func('pos', nor='nor', key='key')

実行結果

pos nor key
pos nor key

任意引数リスト

仮引数名の先頭に*(アスタリスク)を付けることで任意の個数の引数で呼び出せるようにでき、それ以降の引数をキーワード呼び出し専用にすることができます。

def 関数名(*引数):
    なんらかの処理
任意引数リストと記述しましたが値はタプルとして受け取られます

サンプル

以下のサンプルでは引数で受け取った複数の文字列を連結して任意の文字数に分割して返す関数を定義しています。

def func(*s, step=1):
    s = ''.join(s)
    return [s[i:i+step] for i in range(0, len(s), step)]


print(func('abc', 'd', 'efgh', step=2))

実行結果

['ab', 'cd', 'ef', 'gh']

まとめ

この記事では、Pythonの様々な引数について解説しました。

引数を位置専用やキーワード専用にすることで無駄な呼び出し方法を強制して関数の使い方を明確化することができます。

関数の使い方は以下の記事を参照してください。

【Python】関数の定義と呼び出しかた【def文】この記事では、Pythonの関数の定義と使い方を解説します。関数とは、コードをグループ化して名前を付けたものです。関数を定義することで、付けた名前からグループ化した処理を何度も呼び出すことができ、コードの重複を避けることができます。...

それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ