函数装饰器
裝飾器:閉包的一種應用
名字上來看,就是用來裝飾的東西 從
使用上來看,用來‘裝飾’其他函數的函數,可以在原先函數功能基礎上添加新的功能
裝飾器具有一個開放封閉式原則
開放封閉式原則:
1.不能修改被裝飾對象(函數)的源代碼(封閉)
2.不能更改被修飾對象(函數)的調用方式,且能達到增加功能的效果(開放)
開放封閉式原則案例
1.0版本 def fn():print('fn run') fn() 2.0版本 def fn():print('fn run0')print('fn run1')print('fn run2') fn()修改了源代碼,沒有更改調用方式,對外調用方式還是原來的,但功能要有所增加(開放) def fn():print('fn run0')print('fn run')print('fn run2') fn()更改了調用方式,沒有修改原功能代碼(封閉) def wrap(fn):print('fn run0')fn()print('fn run2') wrap(fn)裝飾器:
把要被裝飾的函數作為外層函數的參數通過閉包操作后返回一個代替版函數
被裝飾的函數:fn()
外層函數:outer(func) outer(fn)==>>func=fn
代替版函數:return inner: 原功能+新功能
案例1
def vase():print('插花') def warp(tag):def fn():tag()print('繪畫')return fn vase=warp(vase) vase()裝飾器簡化語法
總結:一個函數可以被任意一個相關裝飾器裝飾,也可以被任意幾個裝飾器裝飾
注:裝飾的順序會影響新增功能的執行順序
有參有返的函數被裝飾
增加一個賬號處理功能:3位及以上英文字符或漢字 def check_use(fn):def inner(use,pwd):if not(len(use)>=3 and use.isalpha()):print('賬號驗證失敗')return Falseresult = fn(use,pwd)return resultreturn inner @check_use 增加一個密碼處理功能:6位及以上英文和數字 def check_pwd(fn):def inner(use,pwd):if not (len(pw))>=6 and pwd.isalnum():print('密碼驗證失敗')return Falseresult = fn(use,pwd)return resultreturn inner @check_use @check_pwd 登錄功能 def login(use,pwd):if use =='abc' and pwd=='123qwe':print('登入成功')return Trueprint('登入失敗')return Falseres=login('abc','123qwe') print(res)裝飾器結合可變長參數
def wrap(fn):def inner(*args, **kwargs):# print(args)# print(kwargs)result = fn(*args, **kwargs)print('新增功能')return result# return inner @wrap def func(a, b, c, *, x, y, z):print(a, b, c, x, y, z)print('原有功能')func(1, 2, 3, x=10, y=20, z=30)登入案例
is_login = False # 登錄狀態def login():global is_loginusr = input('usr: ')if not (len(usr) >= 3 and usr.isalpha()):print('賬號驗證失敗')return Falsepwd = input('pwd: ')if usr == 'abc' and pwd =='123qwe':print('登錄成功')is_login = Trueelse:print('登錄失敗')is_login = False# 完成一個登錄狀態校驗的裝飾器 def check_login(fn):def inner(*args, **kwargs):# 查看個人主頁或銷售功能前:如果沒有登錄先登錄,反之可以進入其功能if is_login != True:print('你未登錄')login()# 查看個人主頁或銷售result = fn(*args, **kwargs)return resultreturn inner# 查看個人主頁功能 @check_login def home():print('個人主頁')# 銷售功能 @check_login def sell():print('可以銷售')home() View Code?
轉載于:https://www.cnblogs.com/wangtenghui/p/10645951.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
- 上一篇: DBD::mysql::db do fa
- 下一篇: 更改eclipse中jsp默认编码格式为