Python里@decorator用法 裝飾器語法在Python中的實際應用解析

裝飾器是python中用于擴展函數或類功能的語法糖,本質是接收函數或類并返回新函數或類的可調用對象。1. 裝飾器通過@符號應用,如@my_decorator裝飾函數等價于將函數傳遞給裝飾器函數并替換原函數;2. 常見用途包括記錄日志/執行時間、權限控制、多層裝飾器疊加使用,例如log_time裝飾器可統一為函數添加耗時統計;3. 多個裝飾器按從下往上的順序依次執行,最靠近函數的裝飾器最先被調用;4. 類也可作為裝飾器,需實現__call__方法,適合需要維護狀態的場景,如緩存結果或計數器。

python中,@decorator 是一種非常實用的語法糖,用來簡化函數或類的裝飾過程。簡單來說,它允許你在不修改原函數代碼的前提下,為其添加額外功能。這在實際開發中特別有用,比如權限校驗、日志記錄、性能統計等場景。


什么是裝飾器(Decorator)

裝飾器本質上是一個函數,也可以是類,它的作用是在不改變原函數調用方式的情況下,對函數的功能進行擴展。Python 中使用 @ 符號來應用裝飾器,放在函數定義的上方。

例如:

@my_decorator def say_hello():     print("Hello")

上面這段代碼等價于:

立即學習Python免費學習筆記(深入)”;

def say_hello():     print("Hello")  say_hello = my_decorator(say_hello)

也就是說,裝飾器就是把一個函數傳給另一個函數,并返回一個新的函數替代原來的函數。


裝飾器的常見用途

1. 記錄日志 / 函數執行時間

這是裝飾器最典型的應用之一。你可以為多個函數統一加上日志輸出或者計時功能,而無需重復寫代碼。

import time  def log_time(func):     def wrapper(*args, **kwargs):         start = time.time()         result = func(*args, **kwargs)         print(f"Call {func.__name__}, cost {time.time() - start:.4f}s")         return result     return wrapper  @log_time def do_something():     time.sleep(0.5)  do_something() # 輸出類似:Call do_something, cost 0.5001s

注意:這里用了 *args 和 **kwargs 來兼容各種參數形式的函數,保證裝飾器的通用性。


2. 權限控制與條件判斷

你可以在執行某個函數前做一些檢查,比如用戶是否登錄、輸入是否合法等。

def login_required(func):     def wrapper(user, *args, **kwargs):         if user.is_authenticated:             return func(user, *args, **kwargs)         else:             print("請先登錄")     return wrapper  class User:     def __init__(self, is_authenticated):         self.is_authenticated = is_authenticated  @login_required def Access_data(user):     print("訪問數據成功")  user = User(is_authenticated=False) access_data(user)  # 輸出:請先登錄

這樣的結構可以讓你集中處理權限邏輯,避免在每個業務函數里都加判斷語句。


3. 多層裝飾器疊加使用

你還可以在一個函數上疊加多個裝飾器,它們會按順序從下往上依次執行。

def decorator1(func):     def wrapper(*args, **kwargs):         print("Start decorator1")         result = func(*args, **kwargs)         print("End decorator1")         return result     return wrapper  def decorator2(func):     def wrapper(*args, **kwargs):         print("Start decorator2")         result = func(*args, **kwargs)         print("End decorator2")         return result     return wrapper  @decorator1 @decorator2 def test():     print("Test function")  test()  # 輸出: # Start decorator1 # Start decorator2 # Test function # End decorator2 # End decorator1

小技巧:多個裝飾器的執行順序是從內到外,也就是最靠近函數的那個最先被調用。


使用類作為裝飾器

除了函數,類也可以作為裝飾器,只需要實現 __call__ 方法即可。

class MyDecorator:     def __init__(self, func):         self.func = func      def __call__(self, *args, **kwargs):         print("Before function call")         result = self.func(*args, **kwargs)         print("After function call")         return result  @MyDecorator def say_hi():     print("Hi")  say_hi()  # 輸出: # Before function call # Hi # After function call

這種方式適合需要維護狀態的情況,比如緩存中間結果、計數器等。


基本上就這些了。裝飾器看起來有點“魔法”,但只要理解它是如何包裝和替換函數的,其實并不難掌握。關鍵是要多練習幾種不同類型的用法,比如帶參數的裝飾器、類方法裝飾器等,才能在實際項目中靈活運用。

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享