decorator(デコレーター)が今一つ分かっていないので簡単な練習。
絵はdecoraotor => decorate => decoration => デコレーションケーキと言う事で。
まずは普通の関数を使ったファイルsample0.pyを作る
def printscript(): print("Hello world") printscript()
これを実行すると
% python3 sample0.py Hello world
これはいつも通り。
これにまずはprint内容を書き換える為のdecoratorを追加。
書き換えたいfunction、deco(func)を書き、書き換えたい先のfunctionの上に@decoと付ける。
deco(func)はdeco(func)の中の関数wrapperを返す(return)ので、それがprintscript()の出力になる。
def deco(func): # decorator関数の宣言、funcにはfunction printscript()が引数として与えられる def wrapper(*args, **kwargs): # デコレーターの中身、*args, **kwargsはデコレートする関数の引数。幾つあっても大丈夫な書き方。 print("Good evening world") return wrapper @deco def printscript(): print("Hello world") printscript()
出力がHello worldでは無く、decoratorで書き換えられたGood evening worldになっているのが分かる。
% python3 Sample0.py Good evening world
次はプリント文を飾ってみたい。
下記をsample01.pyとして保存、実行。
def deco(func): # decorator関数の宣言、funcにはfunction printscript()が引数として与えられる def wrapper(*args, **kwargs): # デコレーターの中身、*args, **kwargsはデコレートする関数の引数。幾つあっても大丈夫な書き方。 print('*'*len("Hello world")) func(*args, **kwargs) # 引数として渡された関数(printscript)を実行 print('*'*len("Hello world")) return wrapper @deco def printscript(): print("Hello world") printscript()
@decoでデコレートする名前の関数deco(func):を設定、このfuncにはデコレートした関数printscriptが引数として与えられる。
中の関数def wrapper(*args, **kwargs):のfunc(*args, **kwargs)でこの引数の関数(printscript)を実行。
今回はこの前後でHello worldと同じ長さの”*”を出力して挟み込むデコレートをする。
正に修飾。
最後にreturnで値を返し、この値が関数printscript()に返された事で、下記の通り出力される。
% python3 sample1.py *********** Hello world ***********
このdecorator, 一旦設定すると色々な関数に使える。
こちらをsample1fl.pyとして保存する。
def deco(func): # decorator関数の宣言、funcにはfunction printscript()が引数として与えられる def wrapper(*args, **kwargs): # デコレーターの中身、*args, **kwargsはデコレートする関数の引数。幾つあっても大丈夫な書き方。 print('*'*len("Hello world")) func(*args, **kwargs) # 引数として渡された関数(printscript)を実行 print('*'*len("Hello world")) return wrapper @deco def printscript(): print("Hello world") printscript() @deco def forloop(): for i in [1, 2, 3, 4, 5]: print(i) forloop()
デコレータは同じモノを使っているが、所与のリスト1〜5の数字を順次出力する関数forloop()を追加した。
printscript()は同じ出力だが、forloop()はどの様に出力するだろうか。
一つ一つにデコレートされるのだろうか?
% python3 sample1fl.py *********** Hello world *********** *********** 1 2 3 4 5 ***********
最初と最後だけにデコレートした行が追加された。
なる程、decoratorは関数forloop()全体をデコレートすると言う理解。
11/10追記:pythonファイルの実行と出力結果のソースコードについて、Visual Studioでの出力結果を記載していた為にターミナル表記と異なっていた点を修正しました。
コメント
[…] Python decoratorの簡単な練習1でやった様にfor loopも測ってみる。5個では少な過ぎるので、100まで(0〜99)の数字で下記のbenchfl.pyを作る。 […]
[…] Python decoratorの簡単な練習1 Python decoratorの簡単な練習1 […]
[…] Python decoratorの簡単な練習1 […]