Python入門 位置引数、キーワード引数、デフォルト引数、便利な引数の使い方(動画あり)

引数について

Pythonでは他のプログラム言語と同様に、関数定義する時に、関数内に変数を渡す方法として引数があります。
関数定義の際に使われるものを仮引数(parameter)、関数呼び出し時に実際に渡す値のことを実引数(argument)と呼びます。
仮引数は0個以上複数設定することができます。
今回はPythonの仮引数の設定方法を説明します。

また、関数の使い方の手引きである、「docstring」の使い方も説明しています。

Pythonの関数で引数の使い方

Pythonでは仮引数の記述の仕方に次のような方法があります。

  • 位置引数:複数の仮引数を書いた場合、仮引数に記述した順番通りに実引数を記述する方法
  • キーワード引数:順番の間違いをなくすため、辞書形式で実引数にキーワードをつける方法
  • デフォルト引数:仮引数にデフォルト値を設定することで、実引数を省略することができる
  • *(アスタリスク)による位置引数のタプル化:*(アスタリスク)を付けることで可変個の位置引数をタプルにまとめることができる
  • **(アスタリスク2つ)によるキーワード引数:**(アスタリスク2つ)を付けることで可変個のキーワード引数を1つの辞書にまとめることができる

位置引数とキーワード引数

位置引数はごく一般的な引数の使い方です。
複数の仮引数を書いた場合、仮引数に記述した順番通りに実引数を記述する方法です。
問題点は引数の数が多くなった場合に、仮引数の位置を確認してないとうまく動作しない点です。

そのような場合に、キーワード引数を使うと間違いがなくなります。
キーワード引数は実引数の方で使用します。仮引数の名前をキーにして「text=’Hey」のように記述します。
位置引数とキーワード引数は混在することができます。

注意点として、位置引数とキーワード引数を混在する場合は、位置引数を先に指定しておく必要があります

位置引数とキーワード引数の例

# キーワード引数の使い方
def hello(text, name):
  print('{}、{}さん'.format(text,name))
  
hello('Tahara', 'Hey')
hello(name='Tahara', text='Hey')

結果
Tahara、Heyさん
Hey、Taharaさん

デフォルト引数

デフォルト引数とは、実引数を指定するときに、同じ値が何度も使われる可能性がある時に指定しておきます。
そうすることで、関数呼び出しの際にデフォルト値の場合、実引数を省略することができます。
そして、もし値がデフォルト値と違った場合のみ実引数を指定することになります。デフォルト値と同じ値の場合にも省略せずに記述することもできます。

デフォルト引数の例

# デフォルト引数の挙動
def hello(name='匿名'):
  print(name)
  
hello()
hello('Tahara')

結果
匿名
Tahara

# 通常の引数とデフォルト引数の混在
def hello(text, name='匿名'):
  print(text,name)

hello('Hey')
hello('Hey','Tahara')

結果
Hey 匿名
Hey Tahara

デフォルト引数は位置引数の後に記述しないとエラーになります。

デフォルト引数を先に記述した例

# デフォルト引数の位置の問題
def hello(name='匿名', text):
  print(text,name)

hello('Tahara','Hey')

結果
File ““, line 1
def hello(name=’匿名’, text):
^
SyntaxError: non-default argument follows default argument

*をつけることで引数をまとめる

関数定義で仮引数の一部として*を使うと可変個の位置引数をタプルにまとめて仮引数にセットすることができます。

位置引数をタプル化した例

def hello(*args):
  print(args)

hello()
hello('Hello')
hello('Hello','world')
hello('Hello','world','aaaaa')
hello('Hello','world','aaaa','bbbbbb')
def hello(*args):

結果
()
(‘Hello’,)
(‘Hello’, ‘world’)
(‘Hello’, ‘world’, ‘aaaaa’)
(‘Hello’, ‘world’, ‘aaaa’, ‘bbbbbb’)

def my_sum(*args):
    return sum(args)
  
print(my_sum(1, 2, 3, 4))

結果
10

*を2つ付けることでキーワード引数を渡す。

2つのアスタリスク(**)を使えばキーワード引数を1個の辞書にまとめることができます。

a=1 が ’a’:1として使える。

**によるキーワード引数の辞書化の例

def hello(**kwargs):
  print(kwargs)
  
hello()
hello(a=1)
hello(a=1,b=2,c=3)

結果
{}
{‘a’: 1}
{‘a’: 1, ‘b’: 2, ‘c’: 3}

*と**を混在させた例

def hello(*args,**kwargs):
  print(args,kwargs)
  
hello()
hello('Hello',a=1)
hello('Hello','world',a=1,b=2,c=3)

結果
() {}
(‘Hello’,) {‘a’: 1}
(‘Hello’, ‘world’) {‘a’: 1, ‘b’: 2, ‘c’: 3}

デフォルト引数の注意点

引数には空のリストをデフォルト引数を指定することができます。
引数のデフォルト値にミュータブルなオブジェクトを指定すると値は初期化されるのではなく追加されます。 これは新たに関数を実行すると新たなメモリを確保するのではなく、前回使用したメモリに追加することになるのです。
このような現象を避けるには、引数の値はイミュータブルな値を指定した方が混乱が起こりません。

デフォルト引数にリストを使った例

def create_int_list(numbers=[]):
  for i in range(1,11):
    numbers.append(i)
  return numbers

numbers = create_int_list()
print(numbers)
numbers = create_int_list()
print(numbers)

結果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

デフォルト引数にリストを使った問題点の例

# 関数を何度も実行すると、値が追加される
def create_int_list(numbers=[]):
  for i in range(1,11):
    numbers.append(i)
  return numbers

numbers = create_int_list()
print(numbers)
numbers2 = create_int_list()
print(numbers2)

結果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Noneを使って検証

PythonにはNoneという特別な値があります。
Noneは値がないことを表すNoneTypeというデータ型唯一の値です。

比較演算子には「==」ではなく「is」を使います。

return文のない関数定義では None が返されます。

Noneはイミュータブルですから、空のリストのような問題が起こりません。次のような記述をすることができます。

デフォルト引数にNoneを使った例

# 初期値を空のリストにするのではなく、Noneにすると関数を実行するごとに初期化される
def create_int_list(numbers=None):
  if numbers is None:
    numbers=[]
  for i in range(1,11):
    numbers.append(i)
  return numbers

numbers = create_int_list()
print(numbers)
numbers2 = create_int_list()
print(numbers2)
numbers3 = create_int_list([-3,-2,1])
print(numbers3)
numbers4 = create_int_list([-3,-2,1])
print(numbers4)

結果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[-3, -2, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[-3, -2, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

デフォルト引数の問題回避例

# 必ず初期化したリストを使いたい場合はローカル変数で初期化する
def create_int_list():
  numbers=[]
  for i in range(1,11):
    numbers.append(i)
  return numbers

numbers = create_int_list()
print(numbers)
numbers2 = create_int_list()

結果
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

フィボナッチ関数の定義

フィボナッチ数列は、「2つ前の項と1つ前の項を足し合わせていくことでできる数列」のことです。数列は「1,1」から始まり、
1, 1, 2, 3, 5, 8, 13, 21…
と続いていきます。

フィボナッチ数列作成コード

def fib(n):
  """
    nまでのフィボナッチ級数を表示
  """
  a,b = 0,1
  while a < n:
    print(a, end=',')
    a,b = b, a+b
 
fib(1000)

結果
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

docstringについて

docstringは、関数の概要とか使い方の説明を記述したものです。
基本的に3重のクオートで囲み関数の命令文の前、先頭に記述します。
オブジェクトの名前や型など、他に調べる方法があるものを記述するのではなく、オブジェクトの目的を短く要約した記述にします。

関数のdocstringを表示するにはhelp()を使います。
通常組み込み関数や、ライブラリ提供された関数には、docstringが書かれています。
積極的に help()を使ってdocstringを読み込んでおきましょう。
引数の使い方が書かれています。機械学習では様々な関数を使いますが、これを知っておくっだけでネット検索の労力が減少されます。
中には細かく引数の使い方を質問する人が時々いますが、help()を見ればわかるはずなのです。

docstringの例

# 自作のfib関数のdocstringを確認
help(fib)

結果
Help on function fib in module __main__:

fib(n)
nまでのフィボナッチ級数を表示

次に、よく使うprint関数のdocstringを確認してみましょう。
意外と知らない、引数を使うことで便利に使えるようになります。

print関数のdocstringを確認

help(print)

結果
Help on built-in function print in module builtins:

print(…)
print(value, …, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.

いろいろなprint関数の引数の使い方

docstringに記述されている、sepとendという引数を使ってみます。
実際にサンプルを動かして、その違いを確認しておきましょう。

ノーマルな例

print('Hello','world')

結果
Hello world

sep=を使った例

print('Hello','world',sep='-')

結果
Hello-world

ノーマルな例

print('Hello')
print('world')

結果
Hello
world

end=を使って例

print('Hello',end=',')
print('world')

結果
Hello,world

参考になった書籍

プログラミングを少しでも経験がありPython の文法を学習する場合は、「入門 Python 3」が良いと思います。長く使えます。

「退屈なことはPython にやらせよう」はオブジェクト指向の解説がないです。代わりにPythonを使った便利な実例が初心者には嬉しい内容です。正規表現から、簡単なスクレイピング 、画像操作などあります。ただし、中級者以上には少し物足りないかもしれません。

Pythonサンプルのダウンロード

ここでダウンロードする「function2.ipynb」ファイルは、このPython動画で使用したものです。

function2.ipynb

Python入門一覧