Python进阶: Decorator 装饰器你太美
生活随笔
收集整理的這篇文章主要介紹了
Python进阶: Decorator 装饰器你太美
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
函數 -> 裝飾器
函數的4個核心概念
1.函數可以賦與變量
def func(message):print('Got a message: {}'.format(message))send_message = func send_message('hello world') #輸出 #Got a message: hello world2.函數可以當作函數的參數
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def get_message(message):return 'Got a message: ' + messagedef root_call(func, message):print(func(message))root_call(get_message, 'hello world') 輸出 #Got a message: hello world3.函數里嵌套函數
def func(message):def get_message(message):print('Got a message: {}'.format(message))return get_message(message)func('hello world') 輸出 #Got a message: hello world4.函數作為函數返回值(閉包)
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def func_closure():def get_message(message):print('Got a message: {}'.format(message))return get_messagesend_message = func_closure() send_message('hello world') #輸出 #Got a message: hello world簡單裝飾器
例
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def my_decorator(func):def wrapper():print('wrapper of decorator')func()return wrapperdef greet():print('hello world')greet = my_decorator(greet) greet()使用語法糖 @
def my_decorator(func):def wrapper():print('wrapper of decorator')func()return wrapper@my_decorator def greet():print('hello world')greet() # 輸出 # wrapper of decorator # hello world帶有參數的裝飾器
直接在 wrapper函數中加上參數
def my_decorator(func):def wrapper(message):print('wrapper of decorator')func(message)return wrapper@my_decorator #相當于 greet == wrapper(message) def greet(message):print(message)greet('hello world') # 輸出 #wrapper of decorator #hello world這個裝飾器只能用在有一個參數的函數,如果想對任意參數的函數通用,可以這么寫
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def my_decorator(func):def wrapper(*args, **kwargs):print('wrapper of decorator')func(*args, **kwargs)return wrapper帶自定義參數的裝飾器
利用裝飾器自定義參數這特性,實現重復執行裝飾器內部函數
def repeat(num):def my_decorator(func):def wrapper(*args, **kwargs):for i in range(num):print('wrapper of decorator')func(*args, **kwargs)return wrapperreturn my_decorator@repeat(4) def greet(message):print(message)greet('hello world')# 輸出: # wrapper of decorator # hello world # wrapper of decorator # hello world # wrapper of decorator # hello world # wrapper of decorator # hello world原函數還是原函數?
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' greet.__name__ #輸出 'wrapper'help(greet) # 輸出 Help on function wrapper in module __main__:wrapper(*args, **kwargs)可以看出,原函數的原信息會被wrapper取代
如果不想其改變,那么可用內置裝飾器@functools.wraps將原函數的元信息拷貝過去。
import functoolsdef my_decorator(func):@functools.wraps(func)def wrapper(*args, **kwargs):print('wrapper of decorator')func(*args, **kwargs)return wrapper@my_decorator def greet(message):print(message)greet.__name__# 輸出 #'greet'類裝飾器
類裝飾器主要依賴于 call()函數,每當調用類實例時,call()函數會被執行一次
class Count:def __init__(self, func):self.func = funcself.num_calls = 0def __call__(self, *args, **kwargs):self.num_calls += 1print('num of calls is: {}'.format(self.num_calls))return self.func(*args, **kwargs)@Count def example():print("hello world")example()# 輸出 # num of calls is: 1 # hello worldexample()# 輸出 # num of calls is: 2 # hello world裝飾器的嵌套
@decorator1 @decorator2 @decorator3 def func():... #相當于 decorator1(decorator2(decorator3(func))) ''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴, 互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' import functoolsdef my_decorator1(func):@functools.wraps(func)def wrapper(*args, **kwargs):print('execute decorator1')func(*args, **kwargs)return wrapperdef my_decorator2(func):@functools.wraps(func)def wrapper(*args, **kwargs):print('execute decorator2')func(*args, **kwargs)return wrapper@my_decorator1 @my_decorator2 def greet(message):print(message)greet('hello world')# 輸出 # execute decorator1 # execute decorator2 # hello world裝飾器的實例用法
1)身份驗證,不登錄不允許操作
import functoolsdef authenticate(func):@functools.wraps(func)def wrapper(*args, **kwargs):request = args[0]if check_user_logged_in(request): # 如果用戶處于登錄狀態return func(*args, **kwargs) # 執行函數 post_comment()else:raise Exception('Authentication failed')return wrapper@authenticate def post_comment(request, ...)...2)日志記錄 可測試函數的執行時間
import time import functoolsdef log_execution_time(func):def wrapper(*args, **kwargs):start = time.perf_counter()res = func(*args, **kwargs)end = time.perf_counter()print('{} took {} ms'.format(func.__name__, (end - start) * 1000))return resreturn wrapper@log_execution_time def calculate_similarity(items):...總結
以上是生活随笔為你收集整理的Python进阶: Decorator 装饰器你太美的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python规范:提高可读性
- 下一篇: Python:值传递,引用传递?不存在的