1. 程式人生 > >裝飾器進階

裝飾器進階

ret out 一個 doc style 實參 返回值 返回 bsp

  • 函數的有用信息
    • 如何給函數添加註釋
    • def func(*args,**kwargs):
          """
           這裏是函數的註釋,先寫?下當前這個函數是?什麽的
          :param args:參數args是什麽意思
          :param kwargs:參數kwargs是什麽意思
          :return:返回值是什麽
          """
          print("哈哈")

    • 如何獲取到函數的相關信息
    •   
      def func(*args,**kwargs):
          """
           這裏是函數的註釋,先寫?下當前這個函數是?什麽的
          :param args:參數args是什麽意思
          :param kwargs:參數kwargs是什麽意思
          :return:返回值是什麽
          
      """ print("哈哈") print(func.__name__) #獲取函數的名字 print(func.__doc__) #獲取函數的註釋
      • 函數名._name_可以查看函數的名字
      • 函數名._doc_可以查看函數的文檔註釋
    • 被裝飾器裝飾之後的函數名
    • def wrapper(func):
          def inner(*args, **kwargs):
              ret = func(*args, **kwargs)
              return ret
          return inner
      # @wrapper 相當於target_func=wrapper(target_func)語法糖
      @wrapper def target_func(): print("我是?標函數") # 調?目標函數 target_func() print(target_func.__name__) # inner 結果: inner
    • 我雖然訪問的是target_func函數,但是實際執行的是inner函數.這樣就會給下遊的程序帶來困惑.我們需要修改函數信息.
    • from functools import wraps # 引?入函數模塊
      #  裝飾器:對傳遞進來的函數進?包裝.可以在?
      def wrapper(func):
          @wraps(func)    # 使?函數原來的名字
      def inner(*args, **kwargs): ret = func(*args, **kwargs) return ret return inner # # @wrapper 相當於target_func=wrapper(target_func)語法糖 @wrapper def target_func(): print("我是?標函數") # 調??標函數 target_func() print(target_func.__name__) # 不再是inner.?是target_func了
    • *args和**kwargs
      • 接受參數的時候是聚合,參數聲明
      • 傳遞參數的時候是打散,給函數傳遞實參
  • 裝飾器傳參
  • def outer(flag):
        def timer(func):
            def inner(*args,**kwargs):
                if flag:
                    print(‘‘‘執行函數之前要做的‘‘‘)
                re = func(*args,**kwargs)
                if flag:
                    print(‘‘‘執行函數之後要做的‘‘‘)
                return re
            return inner
        return timer
    
    @outer(False)
    def func():
        print(111)
    
    func()
    
    帶參數的裝飾器
  • 執行步驟: 先執行outer(False) 然後再@返回值. 返回值恰好是timer. 結果就是 @timer
  • 多個裝飾器裝飾同一個參數
  • def wrapper1(func):
        def inner():
            print(wrapper1 ,before func)
            func()
            print(wrapper1 ,after func)
        return inner
    
    def wrapper2(func):
        def inner():
            print(wrapper2 ,before func)
            func()
            print(wrapper2 ,after func)
        return inner
    
    @wrapper2
    @wrapper1
    def f():
        print(in f)
    
    f()
    
    多個裝飾器裝飾同一個函數
  • 執行順序:首先@wrapper1裝飾起來. 然後獲取到一個新函數是wrapper1中的inner. 然後執行@wrapper2.這個時候. wrapper2裝飾的就是wrapper1中的inner了.
  • 所以. 執行順序就像:
  •     第二層裝飾器前(第一層裝飾器前(目標)第一層裝飾器後)第二層裝飾器後.
  • 程序從左到右執行起來. 就是我們看到的結果

裝飾器進階