Python 裝飾器:為您的函數賦予超能力
你好,有抱負的 Python 程式設計師!今天,我們將深入 Python 裝飾器的神奇世界。將裝飾器想成為可以增強你的函數超能力的魔法包裝紙。很刺激對吧?讓我們一起踏上這次旅程!
裝飾器是什麼?
想像一下你有一個美麗包裝的禮物。包裝紙並不會改變禮物的內容,但它讓禮物看起來更漂亮,對吧?這正是 Python 中裝飾器對你的函數所做的。它們包圍你的函數,添加額外的功能,而不改變原始函數本身。
讓我們從一個簡單的例子開始:
def my_decorator(func):
def wrapper():
print("在函數被調用之前有事情發生。")
func()
print("在函數被調用之後有事情發生。")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
如果你運行這段代碼,你會看到:
在函數被調用之前有事情發生。
Hello!
在函數被調用之後有事情發生。
讓我們來解析一下:
- 我們定義了一個裝飾器函數
my_decorator
,它接受一個函數作為參數。 - 在
my_decorator
內部,我們定義了一個wrapper
函數,它在調用原始函數之前和之後添加一些行為。 - 我們使用
@my_decorator
語法將我們的裝飾器應用於say_hello
函數。 - 當我們調用
say_hello()
時,它實際上是在調用包裝後的函數版本。
這不是很好嗎?我們剛剛為我們的 say_hello
函數添加了一些額外的行為,而沒有修改其代碼!
帶參數的裝飾器
但是等等,還有更多!如果我们的函數需要參數呢?沒問題!我們可以修改我們的裝飾器來處理這個:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("在函數被調用之前。")
result = func(*args, **kwargs)
print("在函數被調用之後。")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
print(add(3, 5))
這將輸出:
在函數被調用之前。
在函數被調用之後。
8
在這裡,*args
和 **kwargs
讓我們的裝飾器可以處理任意數量的位置和關鍵字參數。
內置裝飾器
Python 提供了一些內置的裝飾器,它們非常有用。讓我們來探索它們!
@classmethod 裝飾器
@classmethod
裝飾器用於定義對類本身進行操作的方法,而不是類的實例。
class Pizza:
def __init__(self, ingredients):
self.ingredients = ingredients
@classmethod
def margherita(cls):
return cls(['mozzarella', 'tomatoes'])
@classmethod
def prosciutto(cls):
return cls(['mozzarella', 'tomatoes', 'ham'])
print(Pizza.margherita().ingredients)
print(Pizza.prosciutto().ingredients)
這將輸出:
['mozzarella', 'tomatoes']
['mozzarella', 'tomatoes', 'ham']
在這裡,margherita
和 prosciutto
是類方法,它們用預定義的配料創建並返回新的 Pizza 實例。
@staticmethod 裝飾器
靜態方法是那些不對實例或類進行操作的方法。它們只是碰巧住在類中的普通函數。
class Math:
@staticmethod
def add(a, b):
return a + b
print(Math.add(5, 10))
這將輸出:
15
@property 裝飾器
@property
裝飾器允許你定義可以像屬性一樣訪問的方法。
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@property
def area(self):
return 3.14 * self._radius ** 2
c = Circle(5)
print(c.radius)
print(c.area)
這將輸出:
5
78.5
在這裡,我們可以像訪問屬性一樣訪問 radius
和 area
,但它們實際上是方法。
@functools.wraps 裝飾器
這個裝飾器用於在創建裝飾器時保留原始函數的元數據。
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""這是包裝函數"""
return func(*args, **kwargs)
return wrapper
@my_decorator
def my_function():
"""這是我的函數"""
pass
print(my_function.__name__)
print(my_function.__doc__)
這將輸出:
my_function
這是我的函數
如果没有 @wraps
,函數名和文檔字符串將是包裝函數的。
總結
裝飾器是 Python 中的一個強大功能,它允許你修改或增強函數和方法。它們在框架和庫中被廣泛使用,用於添加如日誌記錄、訪問控制等 功能。
記住,掌握裝飾器的關鍵是實踐。嘗試創建自己的裝飾器並將它們應用於不同的函數。很快,你就會像專業人士一樣將你的函數包裹在超能力之中!
以下是本章涵蓋的裝飾器的總結表:
裝飾器 | 目的 |
---|---|
@classmethod |
定義對類本身進行操作的方法 |
@staticmethod |
定義不對實例或類進行操作的方法 |
@property |
定義可以像屬性一樣訪問的方法 |
@functools.wraps |
在創建裝飾器時保留原始函數的元數據 |
開心編程,願你的函數永遠都被美麗地裝飾!
Credits: Image by storyset