Pythonの中類装飾器の2種類

7678 ワード

pythonのクラスアクセラレータ実装には2種類あります
  • パラメータを持たないクラス装飾器
  • パラメータ付きクラス装飾器
  • 首相は、デコレーションを実現するには、マジックを実現する方法を明確にしなければならない.init__および_call__,以下では、パラメータを持たないクラス装飾器の例を簡単に紹介します.
    import time
    
    #          ,              
    class Foo(object):
    	# init    func
        def __init__(self, func):
            self._func = func
    
        def __call__(self, *args, **kwargs):
            start_time = time.time()
            self._func(*args, **kwargs)
            end_time = time.time()
            print('spend is {}'.format(end_time - start_time))
    
    @Foo  # bar = Foo(bar)
    def bar(a):
        print('【{}】bar..'.format(a))
        time.sleep(2)
    
    
    bar(123)
    

    実行してください
    > python3 test.py
    

    出力は次のとおりです.
    【123】bar..
    spend is 2.0002646446228027
    

    次にパラメータ付きのクラス装飾器を実現します.最大の違いは__です.init__で装飾されたメソッドfuncが伝わらず、funcを__に移行call__で受信し、_init__受信パラメータ
    import time
    
    #         ,              
    class Foo(object):
    	# init         
        def __init__(self, info_="info"):
            self._info = info_
    
    	# call         func
        def __call__(self, func):
        	#          ,   wraps         ,   func 
            def wraps(*args, **kwargs):
                print(self._info)
                start_time = time.time()
                func(*args, **kwargs)
                end_time = time.time()
                print('spend is {}'.format(end_time - start_time))
            return wraps
    
    
    @Foo("【message】")  # bar = Foo(bar)
    def bar(a):
        print('【{}】bar..'.format(a))
        time.sleep(2)
    
    
    bar(123)
    

    実行してください
    > python3 test.py
    

    出力は次のとおりです.
    【message】
    【123】bar..
    spend is 2.000244617462158