Python/関数

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

初歩的な内容[編集]

関数[編集]

いくつかの処理をまとめたものを、プログラミングでは「関数」(かんすう)といいます。数学でいう「関数」とは、意味がちがうので、気をつけてください。

なお英語では、数学の「関数」のことを function (ファンクション)といいます。プログラミング用語の「関数」のことも英語では function といいます。

もとの英語をみれば、どちらにも「数」にあたる英語(number 「ナンバー」など)が無いことに、注目してください。

プログラミングの「関数」では、かならずしも、数(整数や小数などの「数」)をつかう必要は、ありません。


さて、pythonでは、ユーザーが自分で関数をつくることができます。ユーザーによる関数の作成には「def」を用います。「def」とは、おそらく定義を意味する英語 definition の頭3文字です。


def sagyou():
    print("a")
    print("b")

sagyou()
sagyou()
実行結果
a
b
a
b

このように、繰り返し作業をするときなど、関数が便利です。

関数の定義の書式は、

def 関数名():
    処理内容

というふうになります。

関数名のあとに、コロン記号「:」をつけるのを、忘れないようにしてください。

関数の内容は、インデントが終わるまでです。

たとえば下記の関数sagyou()の場合、

def sagyou():
    print("a")
    print("b")

print("c")
sagyou()

関数の内容は、

   print("a")
   print("b")

までです。

print("c")は、関数sagyou()の内容ではないのです。

引数のある関数[編集]

(コード例)
def kansu(a):
    print("計算するよ")
    b = a * 2
    print(a,"を2倍したら",b)

a = 1
kansu(a)

a = 5
kansu(a)

a = 80
kansu(a)

(実行結果↓)

計算するよ
1 を2倍したら 2
計算するよ
5 を2倍したら 10
計算するよ
80 を2倍したら 160

ある処理を繰り返し行いたい場合、関数をつかうことで、記述をへらせます。 関数に作業させる際、関数外で定義された変数を、上記のように利用する事ができ、そのような変数を「引数」(ひきすう)といいます。


上記のコードのうち、関数の定義部分は、

def kansu(a):
    print("計算するよ")
    b = a * 2
    print(a,"を2倍したら",b)

↑ この範囲が、関数の定義部分です。


引数のある関数の定義の書式は、

def 関数名(引数):
    処理内容

というふうになります。

「引数」は「ひきすう」と読みます。


引数が2個以上の場合[編集]

def menseki(a,b):
    print("面積を計算するよ")
    print(a * b)

a = 3
b = 5

menseki(a,b)


結果
面積を計算するよ
15


下記のように、呼び出し時に引数の値を「menseki(3,5)」のように指定することもできます。

def menseki(a,b):
    print("面積を計算するよ")
    print(a * b)

menseki(3,5)


結果
面積を計算するよ
15


やや難しい内容[編集]

関数のローカル性[編集]

a = 10
b = 11

def kansu(a):
    print("計算するよ")
    b = a * 2
    print(a,"を2倍したら",b)

kansu(a)
print("bは",b)
実行結果
計算するよ
10 を2倍したら 20
bは 11

変数bは、関数の中で使われており、関数のなかでbに20が代入されています。

にもかかわらず、関数終了後に、bを呼び出して表示すると、もとの値の11のままです。


このようにpythonでは、関数内で数を置きかえる動作は、原則として、関数外の動作に影響を与えません。


どのような仕組みになっているかというと、関数内で数値が書き換えされた際、pythonでは同名の別変数を新しく作っているのです。(C言語の関数のローカル処理とは、pythonは仕組みが違います。)

pythonではid()という組み込み関数で、変数のid番号(C言語でいう「アドレス」のようなもの)を見る事が出来ますので、確認してみましょう。


a = 10
b = 11

print("aのid",id(a))
print("bのid",id(b))


def kansu(a):
    print("関数の処理中")
    print("aのid",id(a))
    print("計算するよ")
    b = a * 2
    print(a,"を2倍したら",b)
    print("bのid",id(b))
    print("関数の終了")

kansu(a)
print("bは",b)

print("aのid",id(a))
print("bのid",id(b))
実行結果
aのid 140336460552064
bのid 140336460552096
関数の処理中
aのid 140336460552064
計算するよ
10 を2倍したら 20
bのid 140336460552384
関数の終了
bは 11
aのid 140336460552064
bのid 140336460552096

ただし、このように新しいidを用意してくれる場合は、置き換えようとしてる変数が整数や浮動小数といった場合です。

リストの場合、新規のidを用意してくれず、関数内でリストを置きかえると、関数外のもとのリストの内容も変化します。(リストについては『python/リスト』を参照せよ。)


戻り値[編集]

def sagyou():
    print("a")
    print("b")
    return 0

sagyou()
sagyou()
実行結果
a
b
a
b

pythonでは、あまり実用性がないのですが、関数の終了の際に何らかの値を出すことができ、そのような値を 戻り値(もどりち) と言います。

上記のコードでは「0」が戻り値です。return の直後に、戻り値を書きます。

戻り値の0は、特に表示指定しないかぎり、表示されません。


returnがあると、その行で関数が終了とみなされます。


たとえば、もし

def sagyou():
    print("a")
    return 0
    print("b")

sagyou()
sagyou()

とプログラムすると、

実行結果
a
a

のようになります。bは表示されなくなってしまいます。



下記のように引数を使って、計算結果を関数外部に渡すこともできます。しかしpythonでは、この方法は実は、あまり必要ありません。

def kansu(a):
    print("計算するよ")
    b = a * 2
    return b

a = 1
print(a,"を2倍したら",kansu(a))

a = 5
print(a,"を2倍したら",kansu(a))

a = 80
print(a,"を2倍したら",kansu(a))

なぜ、戻り値を渡す方法が、あまり必要ないのかというと、戻り値を渡す方法を使った場合、たとえば上記のコードのように、何回もprint文を書くハメになってしまいます。


他のプログラム言語では、戻り値を「0」とする事により、エラーなく関数が終了した事と扱う慣習があります。(エラーの場合には戻り値が「-1」など、戻り値を0以外の特定の数にする慣習がある。)


キーワード引数[編集]

たとえば、

ミカンが1個あたり100円、リンゴが1個あたり150円としましょう。

買い物のプログラムを書くとしましょう。

(※ まだキーワード引数を使ってません。)

def kaimono(mikan,ringo):
    print("買い物")
    syuppi = 100 * mikan + 150 * ringo
    print("ミカンを",mikan,"個、買います。","リンゴを",ringo,"個、買います。")
    print(syuppi,"円の出費です。")
    
kaimono(1,2)

kaimono(3,1)


実行結果
買い物
ミカンを 1 個、買います。 リンゴを 2 個、買います。
400 円の出費です。
買い物
ミカンを 3 個、買います。 リンゴを 1 個、買います。
450 円の出費です。

べつに上記コードでもいいのですが、 第三者が「kaimono(3,1)」だけ見た場合、3と1のどちらがリンゴの個数で、どちらがミカンの個数か、分からないかもしれません。

なので、下記のように、関数を使う際に、引数欄に「変数名=値」というように引数名を併記する書式で、どの引数にどの値を代入するかを指定して書けます。

(キーワード引数を使ったコードです。)

def kaimono(mikan,ringo):
    print("買い物")
    syuppi = 100 * mikan + 150 * ringo
    print("ミカンを",mikan,"個、買います。","リンゴを",ringo,"個、買います。")
    print(syuppi,"円の出費です。")
    
kaimono(mikan=1,ringo=2)

kaimono(mikan=3,ringo=1)


pythonでは、引数のこういう記法を、キーワード引数と言います。

実行結果
買い物
ミカンを 1 個、買います。 リンゴを 2 個、買います。
400 円の出費です。
買い物
ミカンを 3 個、買います。 リンゴを 1 個、買います。
450 円の出費です。

キーワード引数は、下記のように、引数の順序を入れ替えても平気です。

def kaimono(mikan,ringo):
    print("買い物")
    syuppi = 100 * mikan + 150 * ringo
    print("ミカンを",mikan,"個、買います。","リンゴを",ringo,"個、買います。")
    print(syuppi,"円の出費です。")
    
kaimono(ringo=2,mikan=1)


実行結果
買い物
ミカンを 1 個、買います。 リンゴを 2 個、買います。
400 円の出費です。