def(関数定義)
このページでは豊富な例を用いてPythonのdef(関数定義)の基本を説明します。
defを使用することで関数を定義することができます。
関数は一連の処理を1つの処理体型として切り出すことができ、
うまく利用することでコードの見通しを良くし、変更に強いソフトウェアを作るのに役立ちます。
このページでは基本的な定義方法に限定し解説していきます。
関数はプログラミング言語を習得する上で非常に重要な概念です。
コード例をよく読み、どのように定義し、
どのように利用するかをしっかり理解することは必ずあなたのプログラミングスキルを高めてくれるでしょう。
# 定義方法
def 関数名(引数):
# インデントしたブロック内に関数の処理を記述
TL;DR
基本
# 関数の定義(戻り値なし)
def show_python():
print('python')
# 関数もfunctionクラスのオブジェクトです
print(show_python)
==> <function {環境により異なる文字列}.show_python at {オブジェクト識別値}>
print(type(show_python))
==> <class 'function'>
# 呼び出しには丸括弧()を付ける
# show_pythonの処理は呼び出し時点で実行される
return_value1 = show_python()
==> python
# 明示的にreturnを指定しない場合、戻り値はNone
print(return_value1)
==> None
print(type(return_value1))
==> <class 'NoneType'>
# 関数の定義(明示的な戻り値あり)
def return_python():
return 'Python'
# return_pythonは明示的に'Python'という文字列(str型のオブジェクト)を返している
return_value2 = return_python()
print(return_value2)
==> Python
print(type(return_value2))
==> <class 'str'>
# 関数の定義(明示的な戻り値あり)
def return_float_one():
return 1.0
return_value3 = return_float_one()
print(return_value3)
==> 1.0
print(type(return_value3))
==> <class 'float'>
# 中身が何もない関数は定義できない
def do_nothing():
==> IndentationError: expected an indented block
# passを指定することで処理内容がない関数を定義できる
def do_nothing():
pass
print(do_nothing())
==> None
# 戻り値の型アノテーションを付与することができる
def greet() -> str:
return 'Howdy!'
print(greet())
==> Howdy!
関連情報:type(組み込み関数)の使用方法
引数の定義
# 関数定義、引数(仮引数、parameter)wordを定義
def show_word(word):
# 引数(word)を出力
print(word)
print(type(word))
# 引数(実引数、argument)を与えないとエラー
show_word()
==> TypeError: show_word() missing 1 required positional argument: 'word'
# 引数で与えた文字列が出力される
show_word('Python')
==> Python
==> <class 'str'>
# 引数に数値を与えた場合
show_word(123)
==> 123
==> <class 'int'>
# 関数定義(引数numberを定義して、1を加算した値を戻り値として返す)
def add_one(number):
return number + 1
# 引数(実引数)に100を与える
return_value1 = add_one(100)
print(return_value1)
==> 101
print(type(return_value1))
==> <class 'int'>
# 関数内で(+1)できるようなオブジェクトを引数に与えないとエラー
return_value2 = add_one('apple')
==> TypeError: can only concatenate str (not "int") to str
# 関数定義(複数引数の定義)
def show_arguments(arg1, arg2, arg3):
print('arg1 =', arg1)
print('arg2 =', arg2)
print('arg3 =', arg3)
# 引数が与えた順にそれぞれarg1,arg2,arg3に代入されて関数内で処理される
show_arguments('py', 'js', 'java')
==> arg1 = py
==> arg2 = js
==> arg3 = java
# 引数の順番を変更
show_arguments('js', 'java', 'py')
==> arg1 = js
==> arg2 = java
==> arg3 = py
# 引数が足りない場合はエラー
show_arguments('py', 'js')
==> TypeError: show_arguments() missing 1 required positional argument: 'arg3'
# 引数へも型アノテーションを付与できます
def calculate_square_area(width: int, height: int) -> int:
return width * height
width = 16
height = 5
print(calculate_square_area(width, height))
==> 80
キーワード引数を用いた呼び出し
# 関数定義:仮引数arg1, arg2, arg3を定義
def show_args(arg1, arg2, arg3):
print('arg1 =', arg1)
print('arg2 =', arg2)
print('arg3 =', arg3)
# キーワード引数の指定方法
# 仮引数の名前を指定して引数を指定する
show_args(arg2=1, arg3=20, arg1=300)
==> arg1 = 300
==> arg2 = 1
==> arg3 = 20
# 仮引数arg1に1が代入される
show_args(1, arg3=20, arg2=300)
==> arg1 = 1
==> arg2 = 300
==> arg3 = 20
引数のデフォルト値設定
# 関数定義:仮引数arg1, arg2, arg3を定義し、arg3にはデフォルト値を設定
def show_args(arg1, arg2, arg3='python'):
print('arg1 =', arg1)
print('arg2 =', arg2)
print('arg3 =', arg3)
# 第3引数を与えない場合、仮引数arg3にはデフォルト値が代入される
show_args('javascript', 'kotlin')
==> arg1 = javascript
==> arg2 = kotlin
==> arg3 = python
# 通常通りの呼び出し
show_args('python', 'kotlin', 'javascript')
==> arg1 = python
==> arg2 = kotlin
==> arg3 = javascript
# キーワード引数も使用できる
show_args(arg2='javascript', arg1='kotlin')
==> arg1 = kotlin
==> arg2 = javascript
==> arg3 = python
def calculate_square_area(length=5):
return length * length
# 引数にデフォルト値を設定すると、引数なしでも呼び出すことができます
# 引数を設定しない場合、仮引数lengthにはデフォルト値の5が設定されます
print(calculate_square_area())
==> 25
print(calculate_square_area(10))
==> 100
可変長引数の設定
# *(アスタリスク)を仮引数の前につけると可変長引数として引数を定義できます
def show_args(*args):
# tuple型のオブジェクトとして代入される
print(args)
print(type(args))
for arg in args:
print(arg)
# 1 ~ 3 の引数はtuple型の要素としてargsに代入されます
show_args(1, 2, 3)
==> (1, 2, 3)
==> <class 'tuple'>
==> 1
==> 2
==> 3
# 可変長引数は任意の個数の引数をとるので、呼び出し時に指定しなくてもよい
show_args()
# 引数を指定していないので空のtupleオブジェクトが表示される
==> ()
==> <class 'tuple'>
# 可変長引数の後ろにはキーワード引数のみ定義することができます
def show_mix_args(arg1, *elements, kwarg='python'):
print('arg1 =', arg1)
print('--*elements--')
print(elements)
for arg in elements:
print(arg)
print('--*elements--')
print('kwarg =', kwarg)
# True ~ 'java' までの引数はelementsにtuple型の要素として代入されます
show_mix_args(10, True, False, True, 'java', kwarg='PYTHON')
==> arg1 = 10
==> --*elements--
==> (True, False, True, 'java')
==> True
==> False
==> True
==> java
==> --*elements--
==> kwarg = PYTHON
# 引数の与える順番を変更する。*演算子でlist1を展開してelementsに代入する。
list1 = ['py', 'js', 'java']
show_mix_args('FooBarNinja', kwarg='keyword argument', *list1)
==> arg1 = FooBarNinja
==> --*elements--
==> ('py', 'js', 'java')
==> py
==> js
==> java
==> --*elements--
==> kwarg = keyword argument
# 可変長引数を指定しない場合
show_mix_args('FooBar忍者')
==> arg1 = FooBar忍者
==> --*elements--
==> ()
==> --*elements--
==> kwarg = python
# **を仮引数に指定することで可変長のキーワード引数も指定することができます
def show_variadic_kwargs(**kwarg):
# 可変長のキーワード引数はdict型として仮引数に代入される
print(kwarg)
print(type(kwarg))
for key, value in kwarg.items():
print(key, value, sep=':')
show_variadic_kwargs(name='Ichiro', age=30, sports='baseball')
==> {'name': 'Ichiro', 'age': 30, 'sports': 'baseball'}
==> <class 'dict'>
==> name:Ichiro
==> age:30
==> sports:baseball
# **演算子でdict1を展開してkwargsに代入する
dict1 = {'id': 1, 'name': 'Python', '100': 'one hundred'}
show_variadic_kwargs(**dict1)
==> {'id': 1, 'name': 'Python', '100': 'one hundred'}
==> <class 'dict'>
==> id:1
==> name:Python
==> 100:one hundred
# 可変長引数を指定しない場合
show_variadic_kwargs()
# 引数を指定していないので空のdictオブジェクトが表示される
==> {}
==> <class 'dict'>
# キーの型がstr型じゃない場合はエラー
dict2 = {'id': 1, 'name': 'Python', 100: 'one hundred'}
show_variadic_kwargs(**dict2)
==> TypeError: keywords must be strings
関連情報:forの使用方法
lambda式(ラムダ式)への置き換え
def add_exclamation(element):
return element + '!'
# map関数は引数に関数を取る
list1 = ['A', 'B', 'C']
map1 = map(add_exclamation, list1)
print(list(map1))
==> ['A!', 'B!', 'C!']
# 独自関数を定義する代わりにlambda式を指定できる
list1 = ['A', 'B', 'C']
map2 = map(lambda element: element + '!', list1)
print(list(map2))
==> ['A!', 'B!', 'C!']
# lambda式を変数を代入する場合
# lambdaを識別子に代入するのは非推奨ですが、様々な視点から考えてほしいのであえて例として提示します
lambda_func1 = lambda element: element + '!'
print(lambda_func1('Python'))
==> Python!
# 引数がないlambda式
lambda_func2 = lambda: 10
print(lambda_func2())
==> 10
# 戻り値がないlambda式
lambda_func3 = lambda: print('Lambda!')
lambda_func3()
==> Lambda!
関連情報:lambda式(ラムダ式)の使用方法
関連情報:map関数の使用方法
関連情報:list(リスト・配列)の使用方法
複数の戻り値の設定
# 関数定義:複数の戻り値を返す
def love_args(arg1, arg2):
love = 'Love '
return (love + arg1, love + arg2)
return_value0 = love_args('python', 'javascript')
print(return_value0)
==> ('Love python', 'Love javascript')
print(type(return_value0))
==> <class 'tuple'>
# アンパック代入を用いた場合
return_value1, return_value2 = love_args('python', 'javascript')
print(return_value1)
==> Love python
print(return_value2)
==> Love javascript
# 関数定義:tupleの丸括弧を省略した記述法
def love_args2(arg1, arg2):
love = 'Love '
return love + arg1, love + arg2
解説
基本
defは関数を定義するキーワードです。
関数を定義したブロック内にその関数で行いたい処理を記述し、処理を一つのまとまりにすることができます。
関数を利用したい場合は、()
(丸括弧)を関数名の後ろにつけて呼び出します。
また、関数には戻り値(返り値、原文:return value)というものがあります。
return
文を指定することで明示的に戻り値を指定することができますが、return文以降に書いた関数内の処理は実行されません。
明示的にreturn文を指定しない場合、関数の戻り値はNone
となります。
注意
print関数がコンソール上へ何かを表示すること自体は戻り値ではありません。
print関数のコンソール上への表示は「出力」であり、print関数自体の戻り値はNoneです。
この「出力」と「戻り値」を間違えて理解しているケースが見受けられるので気をつけてください。
# 定義方法
def 関数名(引数):
# インデントしたブロック内に関数の処理を記述
(引数については次項で説明します)
# 関数の定義(戻り値なし)
def show_namaste():
print('Namaste!')
# 関数はfunctionクラスのオブジェクト
print(show_python)
==> <function {環境により異なる文字列}.show_namaste at {オブジェクト識別値}>
print(type(show_namaste))
==> <class 'function'>
# 呼び出しには丸括弧()を付ける
return_value1 = show_namaste()
==> Namaste!
print(return_value1)
==> None
# 関数の定義(明示的な戻り値あり)
def calculate_square_area():
return 10 * 10
# calculate_square_areaは10 x 10の結果(int型のオブジェクト)
return_value2 = calculate_square_area()
print(return_value2)
==> 100
print(type(return_value2))
==> <class 'int'>
# 関数の定義(処理なし)
def nothing():
pass
print(nothing())
==> None
# 関数の定義(戻り値の型アノテーション付き)
def calculate_circle_area() -> float:
return 5 * 5 * 3.14
print(calculate_circle_area())
==> 78.5
関連情報:type(組み込み関数)の使用方法
引数の定義
関数は、関数内で使われる値を関数の呼び出し時に渡すことができます。それを実現するのに用いられるのが引数です。
関数定義時に定義される引数を仮引数(parameter)
、関数呼び出し時に実際に渡される値を実引数(argument)
と呼びます。
この2つの用語は単に「引数」と呼ばれることが多く、文脈からどちらの引数について話されているかを察してください。
引数は複数定義することも可能で、呼び出し時には実引数として渡した順番に、それぞれの値が仮引数部分に設定され内部で処理されます。
次項以降で説明する可変長引数やキーワード引数の指定が特にない場合、
それらの引数は位置引数(positional argument)とも呼ばれ、
デフォルト値(次項以降説明)が設定されていない限り呼び出し時に指定が必須となります。
# 関数定義:引数(仮引数)としてargumentを定義する
def show_argument(argument):
print(argument)
print(type(argument))
# 引数(実引数)を指定しないとエラー
show_argument()
==> TypeError: show_argument() missing 1 required positional argument: 'argument'
# 引数(実引数)に文字列'FooBarNinja'を与える
show_argument('FooBarNinja')
==> FooBarNinja
==> <class 'str'>
# 引数にbool型のTrueを与える
show_argument(True)
==> True
==> <class 'bool'>
# 関数定義:引数(仮引数)としてnumを定義する
def convert_str_to_float(str):
return float(str)
# float型の値が戻り値として得られる
return_value1 = convert_str_to_float('53')
print(return_value1)
==> 53.0
print(type(return_value1))
==> <class 'float'>
# 関数定義(複数引数の定義)
def show_arguments(arg1, arg2, arg3):
print('arg1 =', arg1)
print('arg2 =', arg2)
print('arg3 =', arg3)
return [arg1, arg2, arg3]
ten = 10
twenty = 20
thirty = 30
# 引数が与えた順にそれぞれarg1,arg2,arg3に代入されて関数内で処理される
return_value2 = show_arguments(ten, twenty, thirty)
# show_arguments内のprintの出力
==> arg1 = 10
==> arg2 = 20
==> arg3 = 30
# 戻り値のlist型オブジェクトをprintで出力する
print(return_value2)
==> [10, 20, 30]
# 引数(実引数)の順番を変更すると処理結果も変わる
print(show_arguments(thirty, twenty, ten))
# show_arguments内のprintの出力
==> arg1 = 30
==> arg2 = 20
==> arg3 = 10
# 戻り値のlist型オブジェクト
==> [30, 20, 10]
# 引数が足りない場合はエラー
show_arguments('python')
==> TypeError: show_arguments() missing 2 required positional arguments: 'arg2' and 'arg3'
# 引数への型アノテーション付与
def calculate_triangle_area(base: float, height: float) -> float:
return base * height / 2
return_value3 = calculate_triangle_area(6.0, 10.0)
print(return_value3)
==> 30.0
print(type(return_value3))
==> <class 'float'>
キーワード引数を用いた呼び出し
キーワード引数(keyword arguments)という形式を用いて実引数を指定し関数を呼び出すことができます。
仮引数名=実引数
という形式を用いて、関数呼び出し時に特定の仮引数に値を渡します。
キーワード引数のみを指定して関数を呼び出す場合、定義時に設定された引数の順番に関係なく引数を渡すことができます。
位置引数が指定されている場合は、その後でないとキーワード引数を指定することはできません。
# 関数定義:仮引数arg1, arg2, arg3を定義
def show_args(arg1, arg2, arg3):
print('arg1 =', arg1)
print('arg2 =', arg2)
print('arg3 =', arg3)
# 仮引数の名前を指定して引数を指定する
show_args(arg2=1, arg3=20, arg1=300)
==> arg1 = 300
==> arg2 = 1
==> arg3 = 20
# 仮引数arg1に1が代入される
show_args(1, arg3=20, arg2=300)
==> arg1 = 1
==> arg2 = 300
==> arg3 = 20
引数のデフォルト値設定
引数にはデフォルト値を設定することができます。
仮引数名=デフォルト値
の形式を用いて、関数定義時に仮引数にデフォルト値を設定します。
デフォルト値が設定されている引数は呼び出し時に省略可能で、
その引数を省略した場合は該当部分の引数にデフォルト値が設定されて関数内部の処理が行われます。
また、定義時にデフォルト値を設定する引数は、
デフォルト値を設定しない引数よりも後に定義しなければいけません。
# 関数定義:仮引数arg2とarg3にデフォルト値を設定
def show_args(arg1, arg2=50, arg3=100):
print('arg1 =', arg1)
print('arg2 =', arg2)
print('arg3 =', arg3)
# 第2・第3引数を与えない場合、仮引数arg2とarg3にはデフォルト値が代入される
show_args(0)
==> arg1 = 0
==> arg2 = 50
==> arg3 = 100
# 通常通りの呼び出し
show_args(1, 2, 3)
==> arg1 = 1
==> arg2 = 2
==> arg3 = 3
# キーワード引数も使用できる
show_args(100, arg3=99, arg2=98)
==> arg1 = 100
==> arg2 = 98
==> arg3 = 99
可変長引数の設定
可変長引数とは、関数の呼び出し時に任意の個数の引数を指定できる引数のことです。
仮引数の前に*
(アスタリスク)を付けることで定義します。
関数内では可変長引数として与えた各引数の値が、1つのtupleオブジェクトに格納された状態で仮引数に設定されてあつかわれます。
また、関数定義時に可変長引数の後ろに定義できる引数は、関数呼び出し時にキーワード引数としてのみ指定できる引数になります。
# *(アスタリスク)を仮引数の前につけると可変長引数として引数を定義できます
def show_args(*args):
print(args)
print(type(args))
for arg in args:
print(arg)
# 'foo' ~ 'ninja' の引数はtuple型の要素としてargsに代入されます
show_args('foo', 'bar', 'ninja')
==> ('foo', 'bar', 'ninja')
==> <class 'tuple'>
==> foo
==> bar
==> ninja
# 可変長引数は任意の個数の引数をとるので、呼び出し時に指定しなくてもよい
show_args()
# 引数を指定していないので空のtupleオブジェクトが表示される
==> ()
==> <class 'tuple'>
# 可変長引数の後ろにはキーワード引数のみ定義することができます
def show_mix_args(arg1, *elements, kwarg=100):
print('arg1 =', arg1)
print('--*args--')
print(elements)
for arg in elements:
print(arg)
print('--*args--')
print('kwarg =', kwarg)
# 2 ~ 5 までの引数はelementsにtuple型の要素として代入されます
show_mix_args(10, 2, 3, 4, 5)
==> arg1 = 10
==> --*args--
==> (2, 3, 4, 5)
==> 2
==> 3
==> 4
==> 5
==> --*args--
==> kwarg = 100
# 引数の与える順番を変更する。*演算子でlistを展開してelementsに代入する。
show_mix_args('FooBarNinja', kwarg=1000, *['py', 'js', 'java'])
==> arg1 = FooBarNinja
==> --*args--
==> ('py', 'js', 'java')
==> py
==> js
==> java
==> --*args--
==> kwarg = 1000
# **を仮引数に指定することで可変長のキーワード引数も指定することができます
def show_variadic_kwargs(**kwarg):
# 可変長のキーワード引数はdict型として仮引数に代入される
print(kwarg)
print(type(kwarg))
for key, value in kwarg.items():
print(key, value, sep=':')
show_variadic_kwargs(name='Ichiro', age=30, sports='baseball')
==> {'name': 'Ichiro', 'age': 30, 'sports': 'baseball'}
==> <class 'dict'>
==> name:Ichiro
==> age:30
==> sports:baseball
# **演算子でdict1を展開してkwargsに代入する
dict1 = {'id': 1, 'name': 'Python', '100': 'one hundred'}
show_variadic_kwargs(**dict1)
==> {'id': 1, 'name': 'Python', '100': 'one hundred'}
==> <class 'dict'>
==> id:1
==> name:Python
==> 100:one hundred
# 可変長引数を指定しない場合
show_variadic_kwargs()
# 引数を指定していないので空のdictオブジェクトが表示される
==> {}
==> <class 'dict'>
# キーの型がstr型じゃない場合はエラー
dict2 = {'id': 1, 'name': 'Python', 100: 'one hundred'}
show_variadic_kwargs(**dict2)
==> TypeError: keywords must be strings
関連情報:forの使用方法
lambda式(ラムダ式)への置き換え
内部の処理が簡易かつ使用場面が非常に限られる関数の場合、
lambda式(ラムダ式)への置き換えを検討してみてください。
lambdaというキーワードを用いることにより、
簡易的な関数ならdefを用いず記述することが可能です。
詳しくは以下のlambda式に関するページを参照してください。
def is_odd(num):
return num % 2 == 1
# filter関数は引数に関数を取る
list1 = [1, 2, 3, 4, 5]
filter1 = filter(is_odd, list1)
print(list(filter1))
==> [1, 3, 5]
# 独自関数を定義する代わりにlambda式を指定できる
list1 = [1, 2, 3, 4, 5]
filter2 = filter(lambda e: e % 2 == 1, list1)
print(list(filter2))
==> [1, 3, 5]
# lambda式を変数を代入する場合
# lambdaを識別子に代入するのは非推奨ですが、様々な視点から考えてほしいのであえて例として提示します
lambda_func1 = lambda e: e + '!'
print(lambda_func1('Python'))
==> Python!
# 引数がないlambda式
lambda_func2 = lambda: 'FooBarNinja'
print(lambda_func2())
==> FooBarNinja
# 戻り値がないlambda式
lambda_func3 = lambda: print('Lambda!')
lambda_func3()
==> Lambda!
関連情報:filter関数の使用方法
関連情報:list(リスト・配列)の使用方法
複数の戻り値の設定
関数で複数の戻り値を返したい場合、
戻り値にしたい値すべてを1つのtupleオブジェクトに格納して返す方法があります。
tupleオブジェクト生成時の()
(丸括弧)の省略とアンパック代入(sequence unpacking)を用いることで、
より簡潔に記述することが可能です。
def love_args(arg1, arg2):
love = 'Love '
return (love + arg1, love + arg2)
return_value0 = love_args('python', 'javascript')
print(return_value0)
==> ('Love python', 'Love javascript')
print(type(return_value0))
==> <class 'tuple'>
# アンパック代入(sequence unpacking)を用いた場合
return_value1, return_value2 = love_args('python', 'javascript')
print(return_value1)
==> Love python
print(return_value2)
==> Love javascript
# 関数定義:tupleの丸括弧を省略した記述法
def love_args2(arg1, arg2):
love = 'Love '
return love + arg1, love + arg2