什么是裝飾器?
裝飾器就是用來裝飾函數(shù)。
想要增強原有函數(shù)的功能
但不希望修改原有函數(shù)的定義
在代碼運行期間動態(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)裝飾器使用
定義的裝飾器實質(zhì)是返回函數(shù)的高階函數(shù)
@timeIt(裝飾器名) 這里是 python 提供的一個語法糖
1.解決問題:函數(shù)執(zhí)行前后添加功能-->會改變函數(shù)調(diào)用命令
2.不改變原有函數(shù)的調(diào)用方式-->函數(shù)里面嵌套函數(shù),并且不改變返回嵌套函數(shù)的調(diào)用方式-->login = desc(login)
需求:獲取每個函數(shù)的執(zhí)行時間 #1.函數(shù)執(zhí)行之前計算時間 #2.函數(shù)執(zhí)行之后計算時間 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("所需時間:%.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ù)名:XXX 運行時間:XXXX 運行返回值結(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("[字符串時間:%s] 函數(shù)名:%s 運行時間:%.6f 運行返回值結(jié)果:%s" %(run_time,na,end_time-start_time,res)) return res return wrapper @add_log def mymult(x,y): """這是一個求x的y次方的函數(shù)""" return math.pow(x,y) mymult(2,3)登陸驗證
#用戶登錄驗證的裝飾器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"))類型判斷(無參)
#1.基礎版(無參數(shù)) #編寫裝飾器required_ints # 確保函數(shù)收到的每一個參數(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 # 當裝飾器為@required_types(int,float),確保函數(shù)接收到的每一個參數(shù)都是int/float類型 # 當裝飾器為@required_types(list),確保函數(shù)接收到的每一個參數(shù)都是list類型 # 當裝飾器為@required_types(str,int),確保函數(shù)接收到的每一個參數(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"))帶有多個裝飾器
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 #當有多個裝飾器時,從下到上調(diào)用裝飾器 #真實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)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42276.html
摘要:模塊是一個文件,以結(jié)尾,包含了對象定義和語句模塊讓你能夠有邏輯地組織你的代碼段。把相關(guān)的代碼分配到一個模塊里能讓你的代碼更好用,更易懂。命令執(zhí)行成功,執(zhí)行結(jié)果命令執(zhí)行失敗一秒后執(zhí)行關(guān)機命令 Python 模塊(Module) 是一個 Python 文件,以 .py 結(jié)尾,包含了 Python 對象定義和Python語句 模塊讓你能夠有邏輯地組織你的 Python 代碼段。 把相關(guān)的代...
摘要:什么是包為了組織好模塊,會將多個模塊分為包。處理包也是相當方便的。簡單來說,包就是文件夾,但該文件夾下必須存在文件。最簡單的情況下,只需要一個空的文件即可。當然它也可以執(zhí)行包的初始化代碼包底下也能包含包,這和文件夾一樣,還是比較好理解的。 什么是包? 為了組織好模塊,會將多個模塊分為包。Python 處理包也是相當方便的。簡單來說,包就是文件夾,但該文件夾下必須存在 __init__....
摘要:什么是裝飾者模式今天我們來講另外一個非常實用的設計模式裝飾者模式。就增加功能來說,裝飾者模式相比生成子類更為靈活。下面,裝飾者模式就要正式登場了。下一步,我們可以愉快的去使用裝飾者模式啦 什么是裝飾者模式 今天我們來講另外一個非常實用的設計模式:裝飾者模式。這個名字聽上去有些莫名其妙,不著急,我們先來記住它的一個別名:包裝器模式。 我們記著這兩個名字來開始今天的文章。 首先還是上《設計...
摘要:使用類裝飾器,優(yōu)點是靈活性大,高內(nèi)聚,封裝性。不過不用擔心,有,本身也是一個裝飾器,它的作用就是把原函數(shù)的元信息拷貝到裝飾器函數(shù)中,使得裝飾器函數(shù)也有和原函數(shù)一樣的元信息。 showImg(https://segmentfault.com/img/bVbrFWb?w=742&h=484);Python的裝飾器(decorator)是一個很棒的機制,也是熟練運用Python的必殺技之一。...
摘要:前言繼續(xù)向下看廖大教程,看到了函數(shù)式編程這一節(jié),當時是覺得沒啥用直接跳過了,這次準備要仔細看一遍了,并記錄下一些心得。 前言 繼續(xù)向下看廖大教程,看到了函數(shù)式編程這一節(jié),當時是覺得沒啥用直接跳過了,這次準備要仔細看一遍了,并記錄下一些心得。 函數(shù)式編程 上學期有上一門叫 人工智能 的課,老師強行要我們學了一個叫做 prolog 的語言,哇那感覺確實難受,思維方式完全和之前學過的不一樣,...
閱讀 2588·2019-08-30 10:53
閱讀 3191·2019-08-29 16:20
閱讀 2947·2019-08-29 15:35
閱讀 1767·2019-08-29 12:24
閱讀 2875·2019-08-28 18:19
閱讀 1851·2019-08-23 18:07
閱讀 2331·2019-08-23 15:31
閱讀 1168·2019-08-23 14:05