python基础-装饰器
生活随笔
收集整理的這篇文章主要介紹了
python基础-装饰器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
什么是裝飾器
# 概念:就是接受一個函數不改變里面的代碼,進行包裹,然后返回函數的一個工具;不改變原函數調用方法的,對原函數進行包裹附加功能的工具 # 原理:利用高階函數可以接受函數作為參數,返回函數作為結果實現迭代器 # 功能:極大的簡化代碼,避免編寫重復性代碼函數 # 本質:高階函數# @裝飾器名字:等價于 f = decorate(f)。 # *args-**kw:要讓 @log 自適應任何參數定義的函數,可以利用Python的 *args 和 **kw,保證任意個數的參數總是能正常調用。# 打印日志:@log # 用戶驗證:@auth # 檢測性能:@performance # 數據庫事務:@transaction # URL路由:@post('/register')?
無參數裝飾器:就是沒有參數的裝飾器,一般兩層包裹
# 無參數裝飾器, # 由于decorator返回的新函數函數名已經不是'factorial',而是@log內部定義的'wrapper'。 # 這對于那些依賴函數名的代碼就會失效。decorator還改變了函數的 __name__,__doc__等其它屬性。 # 如果要讓調用者看不出一個函數經過了@decorator的“改造”,就需要把原函數的一些屬性復制到新函數中: # Python內置的functools可以用來自動化完成這個“復制”的任務: 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)# 打印執行時間 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))
有參裝飾器:就是有參數的裝飾器,一般三層包裹
# 有參數裝飾器,三層函數 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)# 內部返回函數名(參數),返回函數名,返回函數名 # 以下是返回的__name__ import time, functools# 沒有加@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("沒有加@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__) # 就是在里面的函數外加個@functools.wraps(函數名的參數名)
?如何使用兩種:原函數和新裝飾器函數
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("--------")# 沒被裝飾的foo.raw()
?
轉載于:https://www.cnblogs.com/adamans/articles/7495523.html
總結
以上是生活随笔為你收集整理的python基础-装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IMO班聊乔月猛:聊天不如聊工作
- 下一篇: vim使用技巧