2022/03/09 関数内関数・クロージャ―の誤記訂正
関数とは
C言語などと同じように何らかの処理をするのが関数とメソッドです。
メソッド
obj.method
関数
func()
メソッドはオブジェクトをどうする、という処理です。
関数は独立した処理です。
関数について説明します。メソッドについても同様なので関数についてのみ説明します。 関数は引数、戻りを持つ場合と持たない場合があります。
# -*- coding: utf-8 -*-
#引数なし戻り値なし
def hello_1():
print("Hello world.")
#引数あり戻り値なし
def hello_2(strGreetig):
print(strGreetig + 'Trump.')
#引数なし戻り値なし
def hello_3():
return 'Japan.'
#引数あり戻り値あり
def hello_4(strGreetig):
print(strGreetig)
return True
def main():
hello_1()
hello_2('Good mornig ')
print('Hello ' +hello_3() )
ret = hello_4('Nice to meet you.')
print(ret)
if __name__ == "__main__":
main()
特に説明する必要がない簡単な例です。hello2とhello4は引数があります。インテリセンスはhello2()と打ち込んだ状態で引数を表示してくれます。
ここで引数がstrGreetingと表示されています。つまり引数は文字列の挨拶になる、ということがわかります。
コーディングルールのところで説明しましたがルールを作って作業すると効率があがります。
パラメータ
hello_2('Good mornig ')以外にも様々なバリエーションがあります。
デフォルトパラメータ
C言語などでも使われています。パラメータを指定しなければデフォルトの値が使われます。
# -*- coding: utf-8 -*-
#デフォルトパラメータ
def default_param(param = 'good morining'):
print(param)
def main():
default_param()
default_param('good night')
if __name__ == "__main__":
main()
実行結果:
good morining
good night
可変長パラメータ
パラメータの先頭に*を付けると可変長パラメータになります。
# -*- coding: utf-8 -*-
def variable_param(*param):
print(param)
def main():
variable_param('Japan' , 'USA', 'England')
if __name__ == "__main__":
main()
実行結果:
('Japan', 'USA', 'England')
辞書型になるパラメータ
パラメータの先頭に**を付けるとj辞書型パラメータになります。
# -*- coding: utf-8 -*-
def dic_param(**param):
print(param)
def main():
dic_param(Japan = 'tokyo' , USA ='Washington', England='London')
if __name__ == "__main__":
main()
実行結果:
{'Japan': 'tokyo', 'USA': 'Washington', 'England': 'London'}
辞書型になっています。
関数のパラメータ
関数もオブジェクトなのでパラメータにすることができます。
# -*- coding: utf-8 -*-
def hogo(pram1, pram2):
print(pram1 + pram2)
def func_param(func, para1, para2):
func(para1, para2)
def main():
func_param(hogo, '本日は', '晴天なり')
if __name__ == "__main__":
main()
実行結果:
本日は晴天なり
Python特有のユニークな関数
関数内関数・クロージャ―です。
# -*- coding: utf-8 -*-
def hoge1(strParam):
str = strParam + " god job"
return str
#クロージャー
def hoge2(strParam):
def addString():
return "ABC " + strParam
return addString()
#関数内関数
def hoge3(strParam):
def addString(a):
return "XYZ " + a
return addString(strParam)
def main():
#通常の関数とパラメータ
func1 = hoge1('Pyton')
print(type(func1))
print(func1)
#クロージャ―
func2 = hoge2('Pyton')
print(type(func2))
print(func2)
func3 = hoge3('Pyton')
print(type(func3))
print(func3)
if __name__ == "__main__":
main()
実行結果:
<class 'str'>
Pyton god job
<class 'function'>
ABC Pyton
<class 'str'>
XYZ Pyton
どれも似たような結果ですが、戻り値がクロージャ―の場合関数になっているのが違いです。
書籍を見てもネットで上位で検索されるサイトを見ても、
関数内関数・クロージャ―を使ってどう幸せになる!
という説明がありません。 一応説明としては、
関数内関数:
複雑な処理を内部の関数に任せることで、コードの重複をさけることに役立つ。
とありますが、上記の例ではそれがわかりません。コードの重複とありますが、まったく意味がわかりません。内部といえばローカル変数があります。もしローカル変数がなかったら、変数のすべてをグローバル変数にすることになります。そうすると、グローバル変数が滅茶苦茶な数になり保守性がわるくなります。ローカル変数のメリットならわかりますが、関数内変数は具体的なメリットがわかりません。わかったら追記します。自分としては多分こんなの使わないと思います。
クロージャ―: 戻り値が関数になっています。この戻り値を実行する func2()
とパラメータで渡された'Python'を記憶していてそれを表示します。しかし、これでどう幸せになるのか?具体的にわかりません。わかったら追記します。
lambda(無名関数)
無名関数とは何なんだぁ―――。
# -*- coding: utf-8 -*-
#lambda 引数:戻り値
def foge(param):
return param + 1
#上記関数と同じ働き
lambda param: param + 1
def main():
print(foge(23))
lambda_func = lambda param: param + 1
print(lambda_func(23))
if __name__ == "__main__":
main()
実行結果:
24
24
lambda 引数:戻り値 で定義されます。
これも短い関数を作らずに済む方法なのですが、ピンと来ません。関数の数を抑止することはドキュメントの記載が少なくなります。しかし、ドキュメントをまじめに書かない人・組織ではどうってことありません。
その他ありますが、本当に役立つか?わからないので割愛します。
|