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("!")

を実行すると、次のような出力結果

                                                                              • -
Are you happy: ? ======================================== I am peace: ('{', '}') I am piyo:
                                                                              • -
I am happy: ! { Yes, as happy as happy can be }: !!

が得られます。

■ 解説

デコレーターが引数を伴うときには「その引数を処理する」関数によって包括するだけです。すると「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


関連記事

Last updated♪2010/02/04