
Decorator 【修飾器】
Python 中的 decorator 是一個修改另一個函數功能的函數。 Decorator 可以被視為使用另一個函數擴展其行為,而不顯式修改它的函數。 由 @ 語法表示,可以在函數或 Class 定義之前使用。
Decorators 實現了以下幾個目標:
程式碼可重用性和 Don't Repeat Yourself 原則: Decorators 允許您定義可重用的構建 blocks,這些構建 blocks 可以更改或擴展其他函數或方法的行為。 它們可以應用於任何需要附加功能的函數或方法,從而提高程式碼的可重用性並遵守 DRY (不要重複自己) 原則。
促進 Separation of concerns: 透過在 decorator 中封裝對函數行為的更改或新加,您可以使主函數的程式碼保持簡潔並更加專注於其主要任務。 這支援了 Separation of concerns (關注點分離) 的設計原則。
在不修改函數程式碼的情況下更改行為: 使用 decorators,您可以在不更改函數 source code 的情況下更改函數的行為。 當您想要向無法或不想更改的函數添加行為時,這會很有用。 例如:向 Python 標準 library 或第三方 library 中的函數,增加日誌記錄、計時功能、記憶性。
Decorators 可以顯著改變它們所裝飾的函數的行為,因此使用它們時要小心。
誤用可能會導致程式碼難以理解、閱讀和 debug。因此應謹慎使用它們並徹底記錄。
範例 – 基礎範例
my_decorator 是一個接受另一個函數作為參數的函數 (在本例中為 say_hello)。 my_decorator 中的 wrapper 函數是一個嵌套 (nested) 函數,它調用 say_hello (原始函數),但還在函數調用之前和之後加入了一些功能。
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# =========================================================
# Replace the decorator
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
def say_hello():
print("Hello!")
decorated_say_hello = my_decorator(say_hello)
decorated_say_hello()執行結果:
帶參數的 Decorators (Decorator factory)
Decorators 也可以接受參數 (arguments)。 以下是定義帶有參數的 decorator 的方法:
scale_and_shift 是一個 decorator factory:返回 decorator 的函數。 當您使用 @scale_and_shift(...) 語法時,您首先調用 scale_and_shift(...),它返回實際的decorator。
Decorator 是一個函數,它接受一個函數 func 作為參數,並返回一個 wraps (包裝) func 的新函數 wrapper。 wrapper 函數使用它收到的任何參數調用 func。
Decorators 應用順序
Python 中的裝飾器按照它們的編寫順序應用,即從最接近函數的位置開始向上。 為了更好地理解這一點,請考慮以下程式碼:
函數 greet() 的輸出被傳遞給 decorator2,然後 decorator2(greet) 的輸出被傳遞給 decorator1。
執行結果:
Python 在函數定義時運行 decorators,而不是在函數調用時運行。 這使得裝飾器適合在定義函數時需要完成一次的任務,例如: 將函數註冊為事件的處理程序。
Syntactic sugar
Syntactic sugar (語法糖) 是一個在編程中使用的術語,用於描述編程語言中的語法,目的在使內容更易於閱讀或表達。 它的目的是讓語言更適合人類使用,也就是說,它使編碼更簡單或更易讀。
與許多語言一樣,Python 也有大量的 syntactic sugar。 這不會改變程式碼的作用; 它只是以不同的方式編寫相同的內容。例如:
Python 中的 decorators 也是一種 syntactic sugar 。函數前面的 @ 符號是 decorator。 它是 syntactic sugar,消除了將 decorator 作為函數本身調用的需要,並使程式碼更清晰。
雖然 syntactic sugar 可以使程式碼更易於閱讀和編寫,但有時也會使其變得更加複雜,特別是對於那些不熟悉所使用的習慣用法和語法的人來說。 因此,需要明智地使用這些工具,並確保可讀性和表達能力。
執行結果:
Last updated
Was this helpful?