什么是裝飾器?
裝飾器就是用來(lái)裝飾函數(shù)。
想要增強(qiáng)原有函數(shù)的功能
但不希望修改原有函數(shù)的定義
在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式
函數(shù)嵌套函數(shù)調(diào)用方式:
原函數(shù) = 外層函數(shù)(原函數(shù)名)
原函數(shù)
def desc(fun): def add_info(): print("happy today") fun() print("westos_linux") return add_info def login(): print("login..") login = desc(login) login()
def add_info(fun): print("happy today") fun() print("westos_linux") def login(): print("login..") def logout(): print("logout..") def save(): print("save..") def trans(): print("trans") add_info(login) add_info(logout) login = add_info(login)裝飾器使用
定義的裝飾器實(shí)質(zhì)是返回函數(shù)的高階函數(shù)
@timeIt(裝飾器名) 這里是 python 提供的一個(gè)語(yǔ)法糖
1.解決問(wèn)題:函數(shù)執(zhí)行前后添加功能-->會(huì)改變函數(shù)調(diào)用命令
2.不改變?cè)泻瘮?shù)的調(diào)用方式-->函數(shù)里面嵌套函數(shù),并且不改變返回嵌套函數(shù)的調(diào)用方式-->login = desc(login)
需求:獲取每個(gè)函數(shù)的執(zhí)行時(shí)間 #1.函數(shù)執(zhí)行之前計(jì)算時(shí)間 #2.函數(shù)執(zhí)行之后計(jì)算時(shí)間 import random import string import time from functools import reduce li = [random.choice(string.ascii_letters +string.digits) for i in range(10) ] def timeit(fun): def wrapper(*args,**kwargs): t1=time.time() res = fun(*args,**kwargs) t2 = time.time() grot = t2-t1 print("所需時(shí)間:%.6f" %grot) return res return wrapper @timeit def myjoin(*args,**kwargs): s = ",".join(*args,**kwargs) print(s) myjoin(li)日志裝飾器
#創(chuàng)建裝飾器 #1.創(chuàng)建add_log裝飾器,被裝飾函數(shù)打印日志信息 #2.日志格式為:[字符串時(shí)間] 函數(shù)名:XXX 運(yùn)行時(shí)間:XXXX 運(yùn)行返回值結(jié)果:XXXX import time import functools import math def add_log(fun): @functools.wraps(fun) def wrapper(*args,**kwargs): run_time =time.ctime() start_time = time.time() res = fun(*args,**kwargs) end_time = time.time() na = fun.__name__ print("[字符串時(shí)間:%s] 函數(shù)名:%s 運(yùn)行時(shí)間:%.6f 運(yùn)行返回值結(jié)果:%s" %(run_time,na,end_time-start_time,res)) return res return wrapper @add_log def mymult(x,y): """這是一個(gè)求x的y次方的函數(shù)""" return math.pow(x,y) mymult(2,3)登陸驗(yàn)證
#用戶登錄驗(yàn)證的裝飾器is_login # 如果用戶登陸成功,則執(zhí)行被裝飾的函數(shù) # 如果用戶登陸不成功,則執(zhí)行登陸函數(shù) users =["root","sheen"] def is_login(fun): def wrapper(*args,**kwargs): if kwargs.get("name") in users: res = fun(*args,**kwargs) else: res = login() return res return wrapper @is_login def writeblog(name): return "wirte,now.." def login(): return "please login.." print(writeblog(name="star"))類型判斷(無(wú)參)
#1.基礎(chǔ)版(無(wú)參數(shù)) #編寫(xiě)裝飾器required_ints # 確保函數(shù)收到的每一個(gè)參數(shù)都是整數(shù) # 如果參數(shù)不是整形數(shù),打印TypeError import functools def required_ints(fun): @functools.wraps(fun) def wrapper(*args,**kwargs): for i in args: if not isinstance(i,int): print("TypeError") break else: res = fun(*args,**kwargs) return res return wrapper @required_ints def myadd(a,b): return a+b print(myadd(1,2.0))含參類型判斷
# #帶參數(shù)的裝飾器 # """ # 裝飾器為required_types # 當(dāng)裝飾器為@required_types(int,float),確保函數(shù)接收到的每一個(gè)參數(shù)都是int/float類型 # 當(dāng)裝飾器為@required_types(list),確保函數(shù)接收到的每一個(gè)參數(shù)都是list類型 # 當(dāng)裝飾器為@required_types(str,int),確保函數(shù)接收到的每一個(gè)參數(shù)都是str/int類型 # 如果參數(shù)不滿足條件,打印TypeError,參數(shù)必須是XXXXX類型 import functools def required_types(*kinds): #kinds元組 def required_ints(fun): @functools.wraps(fun) def wrapper(*args,**kwargs): for i in args: if not isinstance(i,kinds): print("TypeError,參數(shù)類型為",kinds) break else: res = fun(*args,**kwargs) return res return wrapper return required_ints @required_types(int,str) def my(a,b): return a,b print(my(1,"sdhs"))帶有多個(gè)裝飾器
def makebold(fun): print("makebold") def wrapper1(*args,**kwargs): print("bold") return fun(*args,**kwargs) return wrapper1 def makei(fun): print("makei") def wrapper(*args,**kwargs): print("i") return fun(*args, **kwargs) return wrapper #wrapper=login #當(dāng)有多個(gè)裝飾器時(shí),從下到上調(diào)用裝飾器 #真實(shí)wrapper內(nèi)容是從上到下執(zhí)行的 @makebold #login = makebold(login) #login為wrapper1 @makei #login = makei(login) #login為wrapper def login(): return "登陸" print(login())
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/42276.html
摘要:模塊是一個(gè)文件,以結(jié)尾,包含了對(duì)象定義和語(yǔ)句模塊讓你能夠有邏輯地組織你的代碼段。把相關(guān)的代碼分配到一個(gè)模塊里能讓你的代碼更好用,更易懂。命令執(zhí)行成功,執(zhí)行結(jié)果命令執(zhí)行失敗一秒后執(zhí)行關(guān)機(jī)命令 Python 模塊(Module) 是一個(gè) Python 文件,以 .py 結(jié)尾,包含了 Python 對(duì)象定義和Python語(yǔ)句 模塊讓你能夠有邏輯地組織你的 Python 代碼段。 把相關(guān)的代...
摘要:什么是包為了組織好模塊,會(huì)將多個(gè)模塊分為包。處理包也是相當(dāng)方便的。簡(jiǎn)單來(lái)說(shuō),包就是文件夾,但該文件夾下必須存在文件。最簡(jiǎn)單的情況下,只需要一個(gè)空的文件即可。當(dāng)然它也可以執(zhí)行包的初始化代碼包底下也能包含包,這和文件夾一樣,還是比較好理解的。 什么是包? 為了組織好模塊,會(huì)將多個(gè)模塊分為包。Python 處理包也是相當(dāng)方便的。簡(jiǎn)單來(lái)說(shuō),包就是文件夾,但該文件夾下必須存在 __init__....
摘要:什么是裝飾者模式今天我們來(lái)講另外一個(gè)非常實(shí)用的設(shè)計(jì)模式裝飾者模式。就增加功能來(lái)說(shuō),裝飾者模式相比生成子類更為靈活。下面,裝飾者模式就要正式登場(chǎng)了。下一步,我們可以愉快的去使用裝飾者模式啦 什么是裝飾者模式 今天我們來(lái)講另外一個(gè)非常實(shí)用的設(shè)計(jì)模式:裝飾者模式。這個(gè)名字聽(tīng)上去有些莫名其妙,不著急,我們先來(lái)記住它的一個(gè)別名:包裝器模式。 我們記著這兩個(gè)名字來(lái)開(kāi)始今天的文章。 首先還是上《設(shè)計(jì)...
摘要:使用類裝飾器,優(yōu)點(diǎn)是靈活性大,高內(nèi)聚,封裝性。不過(guò)不用擔(dān)心,有,本身也是一個(gè)裝飾器,它的作用就是把原函數(shù)的元信息拷貝到裝飾器函數(shù)中,使得裝飾器函數(shù)也有和原函數(shù)一樣的元信息。 showImg(https://segmentfault.com/img/bVbrFWb?w=742&h=484);Python的裝飾器(decorator)是一個(gè)很棒的機(jī)制,也是熟練運(yùn)用Python的必殺技之一。...
摘要:前言繼續(xù)向下看廖大教程,看到了函數(shù)式編程這一節(jié),當(dāng)時(shí)是覺(jué)得沒(méi)啥用直接跳過(guò)了,這次準(zhǔn)備要仔細(xì)看一遍了,并記錄下一些心得。 前言 繼續(xù)向下看廖大教程,看到了函數(shù)式編程這一節(jié),當(dāng)時(shí)是覺(jué)得沒(méi)啥用直接跳過(guò)了,這次準(zhǔn)備要仔細(xì)看一遍了,并記錄下一些心得。 函數(shù)式編程 上學(xué)期有上一門(mén)叫 人工智能 的課,老師強(qiáng)行要我們學(xué)了一個(gè)叫做 prolog 的語(yǔ)言,哇那感覺(jué)確實(shí)難受,思維方式完全和之前學(xué)過(guò)的不一樣,...
閱讀 2633·2019-08-30 10:53
閱讀 3233·2019-08-29 16:20
閱讀 2991·2019-08-29 15:35
閱讀 1817·2019-08-29 12:24
閱讀 2908·2019-08-28 18:19
閱讀 1896·2019-08-23 18:07
閱讀 2387·2019-08-23 15:31
閱讀 1230·2019-08-23 14:05