Python.use(better) 《余録》デコレーター #5:引数
‖記事一覧‖ Python.use(better)《Python3.1》
デコレーター #5:引数
《著》森こねこ、小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/25 ● 第2版♪2004/06/01 ● 第3版♪2009/02/28
例題によって「基本構文」の理解を深めます。
※ Python2.4 で作成した例題を、Python3.1 で再構成しました。
■ 事例5:引数を伴うデコレーター
次に示すコードの断片
def happy(arg): print("Are you happy:", arg) print("-"*40) print(happy) happy("?") print("="*40) def peace(*args): print("I am peace:", args) l,r = args def piyo(f): print("I am piyo:", f) def yes(arg): print("%s Yes, as happy as happy can be %s:"%(l,r), f(arg)) return yes return piyo @peace("{","}") def happy(arg): print("I am happy:", arg) return arg*2 print("-"*40) print(happy) happy("!")
を実行すると、次のような出力結果
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
が得られます。
■ 解説
デコレーターが引数を伴うときには「その引数を処理する」関数によって包括するだけです。すると「3重の入れ子構造」を持つ関数を定義したことになります。デコレーター構文
@peace("{","}")
を評価すると、関数 peace を呼び出します。すると、次のような出力結果
I am peace: ('{', '}')
が得られます。デコレーター @peace で関数 happy を修飾すると、次に示す
happy = peace("{","}")(happy) #5:
と、同じ効果が得られます。つまり、
- 関数呼び出し peace("{","}") のリターン値として、関数(呼び出し可能オブジェクト)が得られ、
- その関数の実引数に、関数オブジェクト happy を指定した
のと同じです。そのため、
- (#2a)引数 f を介して、関数オブジェクト happy を参照するので、
I am piyo:
という出力結果が得られます。しかも、関数オブジェクト yes をリターン値に指定したので、
- (#2b)組み込み関数 print の引数に happy を指定すると、
このように、関数オブジェクトに関する情報が出力されます。さらに、
- 関数呼び出し happy("!") によって、
{ Yes, as happy as happy can be }: !!
このように、文字列が出力されます。なぜなら、関数を定義したときの名前と同じ
- (#5)変数 happy は、引数を伴うデコレーター @peace("{","}") で装飾された、関数オブジェクト yes を参照する
からです。このとき、局所関数 yes の本体において、
- 関数呼び出し f(arg)
は、
- 関数呼び出し happy("!")
と同じことになるので、次のような文字列
I am happy: !
が「先行して」出力されます。
》こちらに移動中です《
↑TOP