アクセサリーの2、3

12090 ワード

装飾器はPythonの文法のあめとして、今すでに必修の知識点になるべきで、この1篇は私が装飾器のいくつか少し深く考えた後に、書いた1篇の総括的なノートで、みんなの討論を歓迎します
  • 簡単に2つの装飾器
                       ,       ,        ,         ,               。
                 ,          ,                   。
    
  • を言います
    くだらないことはあまり言わないで,やりなさい.
    def func_1(f):
        """
                    
        :param f:   f          
        :return:          
        """
        def inner():
            """
                    ,  f()   f()     ,f   
            :return:        f     
            """
            print('this is func1')
            return f()
        return inner
    

    大丈夫です.テストしてみましょう.
    #          
    def func_2():
        print('func_2')
    
    
    #       
    test_func = func_1(func_2)  # test_func == inner
    
    test_func()  # == inner()
    
    # this is func1
    # func_2
    
    

    結果ok、もし仲間がなぜか分からない場合は、pythonチュートリアルをよく探して見てください.次に、私たちのテストに条件1を追加します.func_の変更は許可されません.2コード、func_2この関数の封版、開放閉鎖の原則に従います2、私はfunc_2()の形式で上記出力の結果を得る
    この二つの条件を見て、少しぼんやりしているのではないでしょうか.この時、頭を働かす必要があります.
  • 条件1はfuncを変更することを許さないと言っています.2のコード、はい、私は変更しないで、私は彼に殻をかぶせて、この时私达は振り返ってただfuncを見ます1()関数、これはinner関数にシェル
  • をセットしたのではないでしょうか.
  • 条件2はfuncを修正することを許さないと言っています.2の呼び出し方法、はい、funcを使います.2()実行しますが、func_2はinnerを指し、最後に実行されるのはinner(シェルされたfunc_2)
  • である.
    完璧
    よし!私たちは一歩一歩一歩:私はまず殻を作って、clothesという名前をつけます(服を着ているようです)
    def clothes(func):
        def inner():
            return func()
    
        return inner
    

    簡単ではない
          tips:        ,         ,              ,       
    

    第二歩:このシェルを加工して、シェルを追加する必要がある関数にパラメータがあることを防ぎます.
    def clothes(func):
        def inner(*args, **kwargs):
            return func(*args, **kwargs)
    
        return inner
    

    ここには知識点があります.1、*argsは不定パラメータです.彼はtuple 2、*argsは変数として宣言できません.彼は関数パラメータの特定のパラメータです.関数宣言がfunc(a,b,c,d)であれば、不定パラメータ*args=(1,2,3,4)を渡すと自動的に一致します.彼はa=1,b=2,c=3,d=4に注意します.まず、*argsで別の関数にパラメータを伝えたい場合は、その関数のパラメータの個数の第2点にマッチして下さい、*argsで変数を宣言することができないため、あの*argsは関数の内部でしか伝達できなくて、それでは説明して、あなたは内部の関数に*argsを伝達することしかできませんここで先にこのようにして、みんなは自分で第3歩を続けることができます:殻に自分のしたいことをさせます
    def clothes(func):
        def inner(*args, **kwargs):
            print('I am a cloth')
            return func(*args, **kwargs)
    
        return inner
    

    ステップ4:関数ハウジング
    def func_2(str1):
        print(str1)
    
    func_2 = clothes(func_2)
    func_2('111')
    # I am a cloth
    # 111
    

    このときfunc_2すでにカバーされていますfunc_2==innerケース完成!初めて見ると少し回りくどいかもしれませんが、皆さんに白状しました.func_2はclothes関数の戻り値を取得するために使用されますが、戻りがintであれば?
    def clothes(func):
        def inner(*args, **kwargs):
            print('I am a cloth')
            return func(*args, **kwargs)
    
        return 1  # int
    
    
    func_2 = clothes(func_2)
    print(func_2)
    # 1
    

    こう見ればわかるかどうか
    これが装飾器の原理であり、装飾器は私たちにもっと便利な文法を与えてくれた.
    def clothes(func):
        def inner(*args, **kwargs):
            print('I am a cloth')
            return func(*args, **kwargs)
    
        return inner
    
    
    @clothes
    def func_2(a):
        print(a)
    
    
    func_2(111)
    

    @clothesは装飾器で、彼を1つの関数の上に押して、下の関数のアドレスをパラメータとして装飾器の関数に渡して、それから戻って装飾された関数(つまりfunc_2)に返します.その時、funcを呼び出します.2関数は、関数の内部を変更することなく、関数呼び出し方法を変更することなく、関数機能を変更することができます.
    基本的な机能が终わって、私达は更に深くなって、inner関数にパラメータの上で私に1つの言叶print(‘I am a cloth’)を印刷することができますか?
    def out(data):
        def clothes(func):
            def inner(*args, **kwargs):
                print(data)
                return func(*args, **kwargs)
    
            return inner
        return clothes
    
    
    @out("abcd")
    def func_2(a):
        print(a)
    

    プロセスヒントを与えます:@out("abcd")は@+out("abcd")1、tmp_を分解しなければなりませんfunc = out(“abcd”) 2、@tmp_func理解したでしょう@演算子と見なし、右側に演算が必要な結果がある場合はint(str(‘a’))に似ています.
    はい、そうしましょう.実は装飾器の前に知っていましたが、原理的には少し問題があったので、長い間引きずっていました.もし問題があれば、討論を歓迎します.