python基础-装饰器
生活随笔
收集整理的這篇文章主要介紹了
python基础-装饰器
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
什么是裝飾器
# 概念:就是接受一個(gè)函數(shù)不改變里面的代碼,進(jìn)行包裹,然后返回函數(shù)的一個(gè)工具;不改變?cè)瘮?shù)調(diào)用方法的,對(duì)原函數(shù)進(jìn)行包裹附加功能的工具 # 原理:利用高階函數(shù)可以接受函數(shù)作為參數(shù),返回函數(shù)作為結(jié)果實(shí)現(xiàn)迭代器 # 功能:極大的簡(jiǎn)化代碼,避免編寫重復(fù)性代碼函數(shù) # 本質(zhì):高階函數(shù)# @裝飾器名字:等價(jià)于 f = decorate(f)。 # *args-**kw:要讓 @log 自適應(yīng)任何參數(shù)定義的函數(shù),可以利用Python的 *args 和 **kw,保證任意個(gè)數(shù)的參數(shù)總是能正常調(diào)用。# 打印日志:@log # 用戶驗(yàn)證:@auth # 檢測(cè)性能:@performance # 數(shù)據(jù)庫(kù)事務(wù):@transaction # URL路由:@post('/register')?
無(wú)參數(shù)裝飾器:就是沒(méi)有參數(shù)的裝飾器,一般兩層包裹
# 無(wú)參數(shù)裝飾器, # 由于decorator返回的新函數(shù)函數(shù)名已經(jīng)不是'factorial',而是@log內(nèi)部定義的'wrapper'。 # 這對(duì)于那些依賴函數(shù)名的代碼就會(huì)失效。decorator還改變了函數(shù)的 __name__,__doc__等其它屬性。 # 如果要讓調(diào)用者看不出一個(gè)函數(shù)經(jīng)過(guò)了@decorator的“改造”,就需要把原函數(shù)的一些屬性復(fù)制到新函數(shù)中: # Python內(nèi)置的functools可以用來(lái)自動(dòng)化完成這個(gè)“復(fù)制”的任務(wù): def log(f):def wrapper(*args,**kwargs):ret = f(*args,**kwargs)print("call "+f.__name__)return retreturn wrapper @log def factorial(n):return reduce(lambda x,y:x*y,range(1,n+1))result = factorial(3) print('result',result)f = log(factorial)(3) print('f',f)# 打印執(zhí)行時(shí)間 import time def performance(f):def wrapper(*args,**kwargs):start = time.time()ret = f(*args,**kwargs)end = time.time()print('call %s() in %f'%(f.__name__,end-start))return retreturn wrapper@performance def factorial(n):return reduce(lambda x,y: x*y, range(1, n+1))print(factorial(10))
有參裝飾器:就是有參數(shù)的裝飾器,一般三層包裹
# 有參數(shù)裝飾器,三層函數(shù) def log1(n):print(n*1000)def outer(f):def wrapper(*args,**kwargs):ret = f(*args,**kwargs)print("call "+f.__name__)return retreturn wrapperreturn outer @log1(8) def factorial(n):return reduce(lambda x,y:x*y,range(1,n+1))result = factorial(3) print(result)f = log1(8)(factorial)(3) print(f)# 內(nèi)部返回函數(shù)名(參數(shù)),返回函數(shù)名,返回函數(shù)名 # 以下是返回的__name__ import time, functools# 沒(méi)有加@functools.wraps(f): def performance(unit):def f(f):def wrapper(*args, **kwargs):t1 = time.time()ret = f(*args, **kwargs)t2 = time.time()if unit == 's':print("call %s() in %s" % (f.__name__, t2 - t1))else:print("call %s() in %s" % (f.__name__, 1000 * (t2 - t1)))return retreturn wrapperreturn f @performance('ms') def factorial(n):return reduce(lambda x, y: x * y, range(1, n + 1)) print("沒(méi)有加@functools.wraps(f):",factorial.__name__)# 有加@functools.wraps(f): def performance(unit):def f(f):@functools.wraps(f)def wrapper(*args, **kwargs):t1 = time.time()ret = f(*args, **kwargs)t2 = time.time()if unit == 's':print("call %s() in %s" % (f.__name__, t2 - t1))else:print("call %s() in %s" % (f.__name__, 1000 * (t2 - t1)))return retreturn wrapperreturn f @performance('ms') def factorial(n):return reduce(lambda x, y: x * y, range(1, n + 1)) print("有加@functools.wraps(f):",factorial.__name__) # 就是在里面的函數(shù)外加個(gè)@functools.wraps(函數(shù)名的參數(shù)名)
?如何使用兩種:原函數(shù)和新裝飾器函數(shù)
def outer(f):def wrapper(*args,**kwargs):ret=f(*args,**kwargs)print("hello2:",*args)return retreturn wrapper@outer def foo(name):print("hello:",name) foo("adamanter")def wrapper(fn):def inner():print("wrapped")fn()inner.raw = fnreturn inner@wrapper def foo():print("go")if __name__ == '__main__':# 被裝飾的foo()print("--------")# 沒(méi)被裝飾的foo.raw()
?
轉(zhuǎn)載于:https://www.cnblogs.com/adamans/articles/7495523.html
總結(jié)
以上是生活随笔為你收集整理的python基础-装饰器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: IMO班聊乔月猛:聊天不如聊工作
- 下一篇: 2017.11.7 Python 制作E