13.Python略有小成(裝飾器)

Python(裝飾器)

1、開放封閉原則

​ 軟件面世時,不可能把全部的功能都設計好,再將來的一兩年功能會陸續上線,按期更新迭代,軟件以前所用的源代碼,函數裏面的代碼以及函數的調用方式通常不會修改,能夠在源碼不改變的狀況下,增長一些新的功能.python

  1. 開放原則 : 在源碼儘可能不改變的狀況下,更新增長一些額外的功能.
  2. 封閉原則 : 不要改變源碼和調用方式

2、初識裝飾器

​ 裝飾器是以功能爲導向的,就是一個函數,在不改變原被裝飾的函數的源代碼以及調用方式下,爲其添加額外的功能.網絡

  1. python中裝飾器 : 完美的詮釋開放封閉原則函數

  2. 裝飾器就是一個函數 : 他要裝飾一個函數,在不改變原函數的源碼以及調用方式的前提下,給其增長一個額外的功能優化

    import time
    def index():
        time.sleep(2)  # 模擬一下網絡延遲以及代碼的效率
        print('歡迎訪問博客園主頁')
    def home(name):
        time.sleep(3)  # 模擬一下網絡延遲以及代碼的效率
        print(f'歡迎訪問{name}主頁')
    def timer(func):  # func = index
        def inner():
            start_time = time.time()
            func()
            end_time = time.time()
            print(f'此函數的執行效率爲{end_time-start_time}')
        return inner
    index = timer(index)
    index()
    # 此爲裝飾器的雛形,雖然知足了開放封閉原則,可是若是當源代碼又返回值時則此代碼不夠完善.

3、被裝飾函數帶返回值

​ 當須要與原代碼返回值一致的時候須要注意一下兩點設計

  1. 明確源代碼的返回值應該返回給誰code

  2. 實際返回給了誰源碼

  3. 如何修改博客

    import time
    def index():
        time.sleep(2)  # 模擬一下網絡延遲以及代碼的效率
        return '歡迎訪問博客園主頁'
    def timer(func):  # func = index
        def inner():
            start_time = time.time()
            ret = func()
            end_time = time.time()
            return ret
        return inner
    index = timer(index)  # inner
    print(index())  # print(inner())
    # 實際的返回值返給了inner,爲了讓返回值與源代碼一致,須要進行賦值操做,這樣就保證了返回值一致
    # 如今代碼已經知足原函數的返回值與裝飾器以後的返回值保持一致了,還缺乏的就是傳參一致.

4、被裝飾函數帶參數的裝飾器

​ 當須要與原代碼傳參保持一致須要注意一下幾點class

  1. 明確源代碼的傳參應該傳參給誰效率

  2. 實際傳參給了誰

  3. 如何修改

    import time
    def home(name,age):
        time.sleep(3)  # 模擬一下網絡延遲以及代碼的效率
        print(name,age)
        print(f'歡迎訪問{name}主頁')
    def timer(func):  # func = home
        def inner(*args,**kwargs):  # 函數定義時,*表明聚合:因此你的args = ('歲月',18)
            start_time = time.time()
            func(*args,**kwargs)  # 函數的執行時,*表明打散:因此*args --> *('歲月',18)--> func('歲月',18)
            end_time = time.time()
        return inner
    home = timer(home)
    home('歲月',18)
    # 這樣利用*的打散與聚合的原理,將這些實參經過inner函數的中間完美的傳遞到給了相應的形參。

5、標準版裝飾器

  • 代碼優化 : 語法糖,Python給咱們提供了一個簡化機制,用一個很簡單的符號去代替相似home = timer(home)這一句話。

    注意 : 由於涉及函數的調用,@timer必定要放在被裝飾函數的上方,不然會報錯.

    def timer(func):  # func = home
        def inner(*args,**kwargs):
            start_time = time.time()
            func(*args,**kwargs)
            end_time = time.time()
        return inner
    @timer  # 此處代替了home = timer(home)
    def home(name,age):
        time.sleep(3)  # 模擬一下網絡延遲以及代碼的效率
        print(name,age)
        print(f'歡迎訪問{name}主頁')
    home('歲月',18)
  • 至此標準版的裝飾器以下,徹底符合代碼開放封閉原則:

    def warpter(f):
      def inner(*args,**kwargs)
          # 此處執行被裝飾函數以前的操做
          ret=f(*args,**kwargs)
          # 此處執行被裝飾函數以後的操做
          return ret
      return inner
相關文章
相關標籤/搜索