1. 程式人生 > >Python學習之路——裝飾器

Python學習之路——裝飾器

源代碼 總結 color lose rgs 方式 pla 添加 func

開放封閉原則:不改變調用方式與源代碼上增加功能

技術分享圖片
‘‘‘
1.不能修改被裝飾對象(函數)的源代碼(封閉)
2.不能更改被修飾對象(函數)的調用方式,且能達到增加功能的效果(開放)
‘‘‘
View Code

裝飾器

# 把要被裝飾的函數作為外層函數的參數通過閉包操作後返回一個替代版函數
# 被裝飾的函數:fn
# 外層函數:outer(func)  outer(fn) => func = fn
# 替代版函數: return inner: 原功能+新功能

def fn():
    print("原有功能")

# 裝飾器
def outer(tag):
    
def inner(): tag() print(新增功能") return inner fn = outer(fn) fn()

語法糖@外層函數

技術分享圖片
def outer(f):
    def inner():
        f()
        print("新增功能1")
    return inner
              
def wrap(f):
    def inner():
        f()
        print("
新增功能2") return inner @wrap # 被裝飾的順序決定了新增功能的執行順序 @outer # <==> fn = outer(fn): inner def fn(): print("原有功能")
View Code

有參有返的函數被裝飾

def check_usr(fn):  # fn, login, inner:不同狀態下的login,所以參數是統一的
    def inner(usr, pwd):
        # 在原功能上添加新功能
        if not
(len(usr) >= 3 and usr.isalpha()): print(賬號驗證失敗) return False # 原有功能 result = fn(usr, pwd) # 在原功能下添加新功能 # ... return result return inner @check_usr def login(usr, pwd): if usr == abc and pwd ==123qwe: print(登錄成功) return True print(登錄失敗) return False # 總結: # 1.login有參數,所以inner與fn都有相同參數 # 2.login有返回值,所以inner與fn都有返回值 """ inner(usr, pwd): res = fn(usr, pwd) # 原login的返回值 return res login = check_usr(login) = inner res = login(‘abc‘, ‘123qwe‘) # inner的返回值 """

裝飾器最終寫法

def wrap(fn):
    def inner(*args, **kwargs):
        print(前增功能)
        result = fn(*args, **kwargs)
        print(後增功能)
        return result
    return inner

@wrap
def fn1():
    print(fn1的原有功能)
@wrap
def fn2(a, b):
    print(fn2的原有功能)
@wrap   
def fn3():
    print(fn3的原有功能)
    return True
@wrap
def fn4(a, *, x):
    print(fn4的原有功能)
    return True

fn1()
fn2(10, 20)
fn3()
fn4(10, x=20)

Python學習之路——裝飾器