python装飾器はなぜ2層のネストが必要なのかについても話します.

3041 ワード

記事には次の内容が含まれています.
1、装飾器の文法構造と運行順序はどうなっていますか.
2、どうして2階の装飾器が必要ですか.単層の装飾器はどうして間違っていますか? 'NoneType' object is not callable .修正された単層装飾器はなぜ推奨されないのですか?
3,python言語の設計者はなぜ彼を2階建てに設計したのか.
最近装饰器を勉强して、过程の中で多くの困难に出会って、今大体解决して、今いくつかの経験をみんなに分かち合います.初学なので、間違いがあるかもしれませんが、議論を指摘してください.
1、装飾器の文法構造と運行順序
def log(func):                                         #1
    def wrapper(*args, **kw):                          #2
        print('call %s():' % func.__name__)            #3
        return func(*args, **kw)                       #4
    return wrapper                                     #5
@log                                                   #6
def now():                                             #7
print('2015-3-25')                                     #8

上は簡単な装飾器で、2階に分かれていて、
外層#1は、装飾された関数a,#5 return装飾された関数、すなわち内層関数bとして装飾器の名前を定義する.
内層b 2は関数aのパラメータを導入して修飾し、#4 returnが装飾された関数a(),(括弧付きであることに注意)
これは装飾器の標準的な文法構造です.
装飾器の運転手順についてお話しします
ルール1では、プログラムが#6@logと読むと上の装飾器の外層が実行され、このとき外層にprintがあるとそのまま印刷され、
ルール2,#7#8は装飾された関数aを読み出す
ルール3,#5,returnが装飾された関数bは,このときaがbを指し,その後aを呼び出すとbを呼び出す.
これで上のコードが実行され、その後aが呼び出されると
now()

装飾された関数bを直接実行します
2、どうして2階の装飾器が必要ですか.
単層の装飾器を直接使うと
def log(func):                                         #1
    print('call %s():' % func.__name__)                #2
    return func()                                      #3 
@log                                                   #4
def now():                                             #5
    print('2015-3-25')  

このとき#4の実行時に#2のprintが実行され、装飾器は関数の値ではなく#3 returnの関数を要求する(正確な書き方は
return func

)のため、#3の構文エラーは、'NoneType'object is not callable
3括弧を使わない書き方に直すと
def log(func):                                         #1
    print('call %s():' % func.__name__)                #2
    return func                                        #3 

を選択すると、エラーは報告されませんが、@logのときに直接デザイナの内容(ルール1)が実行されます.つまりprintが実行されると、デザイナは元の関数a(ルール3)を返します.したがって、その後、関数aを呼び出すとデザイナをトリガーできません
3,pythonの設計者はなぜこのように設計したのですか.
なぜ単層の装飾器の実行順序を現在の二層装飾器の実行順序に等価にしないのか
1つは,2層構造が装飾された関数aのパラメータを伝達できることである.
二つ目は、関数aと関数logの元の構造を変更しないことです.log自体が関数であり、他の関数と同じ実行順序を持っているからです.
@log
def now():
    pass
完全にnow=log(now)に等しい
まずこのようにして、補充しなければならない.
参考資料:
1、装飾器-廖雪峰の公式サイト
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000#0
2,python装飾器なぜ二重ネスト関数を必要とするのか-SegmentFault思No
https://segmentfault.com/q/1010000006990592
3、python装飾器はなぜ2階建てでネストされているのですか?-CSDNブログhttps://blog.csdn.net/u010770184/article/details/530990894,[python]Pythonアクセサリーの理解についての心得を共有して参考にしてください.
https://www.tuicool.com/articles/FBZvya  
この文章は誤りがあって、もし単層の装飾器を使うならば、後で関数a(括弧をつけない)を呼び出して、関数はいかなる操作を実行しないで、もちろん間違いも報告しません