基本編では、Pythonが提供する組み込み関数を何度も使用してきました
関数は、なんらかの機能を提供する処理を再利用しやすい形にまとめたものです
何度も似たような処理を書いている場合、関数にしてまとめることにより、プログラムを簡潔に作成できることがあります
ここでは、関数を作成する方法について説明をしていきます
関数について
独自の関数を定義するには、def(デフ)というキーワードを使用して以下のように記述します
def 関数名(引数,引数,,,):
文
…
defの後に関数名、コロン(:)を記述後、改行し、次の行からインデントして記述します
インデントしている間は関数の内側として扱われ、インデントをやめると関数の外側として扱われます
関数名は変数と同様に自由につけることができますが、英小文字を使うことが推奨されています
引数と戻り値
関数から、戻り値を返す場合もあります
関数から戻り値を返す場合、return文を使用します
def 関数名(引数,引数,,,):
文
文
return 式
式を評価した結果の値が戻り値として関数の呼び出し元に戻ります
式の部分には値や変数、関数呼び出しや、これら演算子を組み合わせたものなどを書くことができます
関数を用いた場合の処理の流れのイメージ図は下図のようになります

①呼びだし側の先頭からadd関数までの処理を実行
②呼び出し側で定義した値を引数として、add関数を呼び出す
③add関数内の引数に②で渡した値が渡され、add関数で処理を実行した結果を戻り値とする
④呼び出し元へ戻り、関数からの戻り値を代入する
⑤add関数の後の処理を実行する
関数の定義に記述する引数のことを「仮引数」、関数を呼び出すときに渡す引数のことを「実引数」とよびます
上図では、呼び出し側のx,yが実引数、add関数の引数a,bが仮引数です
関数を定義したときの仮引数の順序と関数を呼び出すときの実引数の順序は一致させる必要があり、これを「位置引数」と言います
以下は、引数の値でグー、チョキ、パーを表示するプログラムです
import random
def judge(num):
print("あなたの手は"+str(num)+"です。")
if num == 0:
return "グー"
elif num == 1:
return "チョキ"
elif num == 2:
return "パー"
else:
return "エラー"
s = judge(random.randint(0,2))
print(s)
実行結果
あなたの手は2です。
パー
judge関数を作成し、入力した値によりグー、チョキ、パーを表示します
呼び出し側はランダムを使用して取得した値をjudge関数に引数として渡しています
最後に、judge関数からの戻り値を表示しています
また、アスタリスク(*)を使い、実引数に「*イテラブル」と記述するとイテラブルから要素を取り出し、各要素を別々の引数として渡すことができます
イテラブルとは、繰り返し可能なオブジェクト、または反復可能なオブジェクトを意味し、リストやタプル、文字列、辞書、集合などのデータ型がイテラブルです ※for ループで処理できるものすべてがイテラブルに該当します
以下にキーワード引数で記述したサンプルプログラムを示します
def print_menu(item,price,calorie):
print("*****")
print("商品名:"+item)
print("価格:"+str(price)+"円")
print("カロリー:"+str(calorie)+"kcal")
# 引数3個を保持したリストを作成し関数に渡す例
menu = ["サラダ",350,192]
print_menu(*menu)
# 引数2個を保持したリストとcalorieの値を関数に渡す例
menu = ["スープ",150]
print_menu(*menu,154)
実行結果
*****
商品名:サラダ
価格:350円
カロリー:192kcal
*****
商品名:スープ
価格:150円
カロリー:154kcal
変数のスコープ(有効範囲)
変数のスコープは変数を作成する場所によって異なってきます
関数の内側で変数を作成した場合、「ローカル変数」になり、関数の外側で作成した場合は「グローバル変数」になります
ローカル変数
ローカル変数はその変数を作成した関数の内側からのみ参照でき、他の関数からは参照できません
そのため、ある関数内で作成した変数名と同じ変数名を、他の関数のローカル変数として作成しても、それぞれの関数内部で作成した変数を参照します
以下にローカル変数を使ったサンプルプログラムを示します
def hello():
text = "Hello!"
print("in hello():" + text)
def bye():
text = "Good Bye!"
print("in bye():" + text)
hello()
bye()
実行結果
in hello():Hello! → hello()関数内でローカル変数textを表示
in bye():Good Bye! → bye()関数内でローカル変数textを表示
一方、以下のように関数の内部で定義したローカル変数を関数の外から参照しようとするとエラーが発生します
def hello():
text = "Hello!"
print("in hello():" + text)
def bye():
text = "Good Bye!"
print("in bye():" + text)
hello()
bye()
print(text)

また、以下のように関数内で定義したローカル変数を他の関数から参照しようとしてもエラーが発生します
def func1():
z = 1
def func2():
print(z)
func1()
func2()

グローバル変数
グローバル変数は関数の外側はもちろん、どの関数の内側からでも参照することができます
def func1():
print(z)
z = 1
func1()
実行結果
1
グローバル変数と同じ名前のローカル変数を作成することができますが、ローカル変数を作成した関数の内側ではローカル変数が優先されます
def hello():
text = "Hello!"
print("in hello():" + text)
text = "Hi!"
print("in main():" + text)
hello()
print("in main():" + text)
実行結果
in main():Hi!
in hello():Hello!
in main():Hi!
【演習問題】
- 以下の機能をもつ関数を作成しましょう
(1) 2つの整数の⼤きい⽅を求める関数を実装する
※同じ値の場合は、1番目の引数を返す仕様とする
(2) 標準⼊⼒より、2つの整数を取得し、(1)で作成した関数を呼び出す
(3) (2)の結果を出⼒する
実行結果
1番目の整数を入力してください:4
2番目の整数を入力してください:6
4と6の大きい方は6です。
- 以下の機能をもつ関数を作成しましょう
(1) 2つの整数の⼩さい⽅を求める関数を実装する
※同じ値の場合は、1番目の引数を返す仕様とする
(2) リストを⽤意し、1から100までの乱数を5個代⼊し、代⼊した値を表⽰する
(3) (1)の関数を使⽤し、リストの最⼩値を求める
実行結果
[63, 32, 3, 67, 47]
3
- 以下の機能をもつ関数を作成しましょう
(1) うるう年かどうかを判定する関数を作成する
(2) 1900年から2024年までの間でうるう年と判定した年を列挙する
※うるう年の判定⽅法は次の通り
* ⻄暦が4で割り切れる
* ただし、100で割り切れる場合は、うるう年にはしない
* 例外として400で割り切れる場合は、うるう年とする
実行結果
1904 1908 1912 1916 1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000 2004 2008 2012 2016 2020 2024
キーワード引数
「位置引数」は、関数を定義したときの仮引数の順序と、関数を呼び出すときの実引数の順序は一致させる必要があると説明していました
一方、「キーワード引数」を使うと、仮引数の順序とは異なる順序で、関数を呼び出すときの実引数を指定することができます
下記のように、キーワード引数は「引数名=値」の形式で記述します
# 関数の定義
def 関数名(引数A,引数B,引数C):
文
# 関数の呼び出し
関数名(引数B=値B,引数C=値C,引数A=値A)
以下にキーワード引数で記述したサンプルプログラムを示します
def get_bmi(height,weight):
print("height="+str(height))
print("weight="+str(weight))
return weight / (height/100)**2
h = float(input("身長(cm)を入力してください:"))
w = float(input("体重(kg)を入力してください:"))
bmi = get_bmi(weight=w,height=h)
print("BMIは"+str(bmi)+"です。")
実行結果
身長(cm)を入力してください:165
体重(kg)を入力してください:56
height=165.0
weight=56.0
BMIは20.569329660238754です。
また、位置引数とキーワード引数を混在させる場合は、位置引数を先(キーワード引数の左側)に書く必要があります
以下に位置引数とキーワード引数を混在したサンプルプログラムを示します
def print_menu(item,price,calorie):
print("*****")
print("商品名:"+item)
print("価格:"+str(price)+"円")
print("カロリー:"+str(calorie)+"kcal")
# 位置引数
print_menu("サラダ",350,192)
# 混在
print_menu("サラダ",calorie=192,price=350)
実行結果
*****
商品名:サラダ
価格:350円
カロリー:192kcal
*****
商品名:サラダ
価格:350円
カロリー:192kcal
itemを位置引数で指定し、priceとcalorieをキーワード引数で指定した例です
位置引数はキーワード引数よりも先に定義しています
一方、以下のように記述すると、位置引数のitemがキーワード引数のpriceやcalorieの後にあるので、エラーが発生します

また、アスタリスク(*)を2個使い、実引数に「**辞書」と記述すると、辞書からキーと値の組を取り出し「キー=値」というキーワード引数として関数にわたすことができます
def print_menu(item,price,calorie):
print("*****")
print("商品名:"+item)
print("価格:"+str(price)+"円")
print("カロリー:"+str(calorie)+"kcal")
menu = {"item":"サラダ","price":350,"calorie":192}
print_menu(**menu)
実行結果
*****
商品名:サラダ
価格:350円
カロリー:192kcal
デフォルト引数
関数の引数には「デフォルト値」を設定することができます
関数を呼び出す際に、実引数を省略すると代わりに設定したデフォルト値が使われます
デフォルト値を設定するには以下のように記述します
def 関数名(引数A=デフォルト値A,引数B=デフォルト値B,,):
文
def 関数名(引数A,引数B,,引数C=デフォルト値C,引数D=デフォルト値D,,):
文
一部の引数だけデフォルト値を設定する場合、デフォルト値がない引数を左に、デフォルト値がある引数を右に記述します
引数のflgの値で、引数で受け取った値のどちらかを返す関数を以下のように作成します
それぞれ、デフォルト引数を設定しています
def get_value(x1=0,y1=0,flg=1):
if flg == 1:
return x1
elif flg == 2:
return y1
else:
return "エラー"
print(get_value(3,5))
print(get_value(3,5,2))
print(get_value())
実行結果
3
5
0
get_value(3,5)の場合、flgの実引数が指定されていないのでflgの値はデフォルト値:1が代入されます
get_value()の場合、すべての実引数が定義されていないので、x1、y1、flgともデフォルト値が使用されます
可変長引数
可変長引数とは、個数が任意の引数のことです
可変長引数の関数を定義するには、アスタリスク(*)を使い、仮引数に「*引数」または「**引数」と書きます
「*引数」は任意個の位置引数をタプルとして受け取り、「**引数」は任意個のキーワード引数を辞書として受け取ります
可変長引数の例として、print関数の定義を以下に示します
print(*objects, sep=' ', end='\n', file=None, flush=False)
printは関数上記のように定義されています
objects を sep で区切りながらテキストストリーム file に表示し、最後に end を表示します
objectsは位置引数であり、sep 、 end 、 file 、 flush はキーワード引数で省略された場合はデフォルト値が与えられます
objectsは任意個の位置引数とタプルとして受け取る可変長引数として定義されています
参考:https://docs.python.org/ja/3.13/library/functions.html#print
print("Hello World",end="!")
実行結果
Hello World!
print("Hello","World",sep="!")
実行結果
Hello!World
このサンプルでは”Hello”,”World”の引数をタプルとして受け取っています
キーワード可変長引数を使ったサンプルプログラムを以下に示します
def print_menu(**kwargs):
print("*****")
print("商品名:"+kwargs["item"])
print("価格:"+str(kwargs["price"])+"円")
print("カロリー:"+str(kwargs["calorie"])+"kcal")
print()
print("*****kwargsのdump")
for key,value in kwargs.items():
print(key+":"+str(value))
menu = {"item":"サラダ","price":350,"calorie":192}
print_menu(**menu)
print()
print_menu(item="スープ",price=150,calorie=154)
実行結果
*****
商品名:サラダ
価格:350円
カロリー:192kcal
*****kwargsのdump
item:サラダ
price:350
calorie:192
*****
商品名:スープ
価格:150円
カロリー:154kcal
*****kwargsのdump
item:スープ
price:150
calorie:154
- def print_menu(**kwargs):**kwargsと記載することで、任意の数のキーワード引数を受け取れるようになります
- kwargsは辞書型のため、各キーの値をkwargs[“item”]、kwargs[“price”]、kwargs[“calorie”]として取得しています
- for key, value in kwargs.items():: kwargsは辞書型として扱われるので、items()メソッドを使ってキーと値のペアをループで取り出します
- print_menu(**menu)で定義した辞書を引数として関数を呼び出しています
- print_menu(item=”スープ”,price=150,calorie=154): item, price, calorieというキーワード引数を指定して関数を呼び出しています
【演習問題】
- 可変長の数値の引数を受け取り、その合計を返す関数を作成する
関数は以下のような関数を作成する
def sum_number(*args):
処理
- 可変数の位置引数とキーワード引数の両方を受け取り、それらをすべて出力する関数を作成する
関数は以下のような関数を作成する
def print_all_arguments(*args, **kwargs):
処理
実行結果(例)
位置引数:
1
2
3
キーワード引数:
name: Bob
age: 25
country: Canada
コメント