Python中的裝飾器是什么?
在Python的世界里,裝飾器是一種非常強大而優(yōu)雅的工具,它允許程序員在不修改原有函數(shù)代碼的前提下,增加函數(shù)的功能。
本文將向大家詳細介紹什么是裝飾器,它是如何工作的,以及如何在自己的代碼中使用裝飾器。
什么是裝飾器
裝飾器本質(zhì)上是一個函數(shù),它可以讓其他函數(shù)在不改變自身代碼的情況下增加額外的功能。裝飾器的使用非常廣泛,比如:記錄日志、性能測試、事務處理、緩存、權(quán)限校驗等等。
裝飾器的基本使用
裝飾器的使用非常簡單,只需要在需要被裝飾的函數(shù)上方添加一個@裝飾器名即可。下面通過一個簡單的例子來說明裝飾器的基本使用。
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()
運行這段代碼,輸出將會是:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
在這個例子中,my_decorator就是一個裝飾器,它接受一個函數(shù)func作為參數(shù),并返回一個新的函數(shù)wrapper。wrapper函數(shù)中加入了在func執(zhí)行前后需要執(zhí)行的代碼。通過@my_decorator,我們將這個裝飾器應用到了say_hello函數(shù)上。
裝飾器中傳遞參數(shù)
如果我們的函數(shù)有參數(shù)怎么辦?裝飾器也能很好地處理這種情況。看下面的例子:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Something is happening before the function is called.")
result = func(*args, **kwargs)
print("Something is happening after the function is called.")
return result
return wrapper
@my_decorator
def say(message):
print(message)
say("Hello with argument!")
這段代碼中,wrapper函數(shù)使用了*args和**kwargs來接受任意數(shù)量和類型的參數(shù),這使得裝飾器變得更加靈活。
使用多個裝飾器
Python也支持給一個函數(shù)同時使用多個裝飾器,如下所示:
def decorator_one(func):
def wrapper():
print("Decorator one!")
func()
return wrapper
def decorator_two(func):
def wrapper():
print("Decorator two!")
func()
return wrapper
@decorator_one
@decorator_two
def say_hello():
print("Hello!")
say_hello()
當使用多個裝飾器時,它們的執(zhí)行順序是從近到遠,即先decorator_two后decorator_one。
真 實例子: 計算函數(shù)執(zhí)行所需時間
現(xiàn)在 通過一個更實際的例子來進一步理解裝飾器: 假設我們要編寫一個裝飾器,用于計算任何函數(shù)執(zhí)行所需的時間。 這在性能測試時非常有用。
import time
# 創(chuàng)建一個裝飾器,它會計算并打印函數(shù)執(zhí)行所需的時間
def time_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time() # 記錄函數(shù)開始執(zhí)行的時間
result = func(*args, **kwargs) # 執(zhí)行函數(shù)
end_time = time.time() # 記錄函數(shù)執(zhí)行完成的時間
print(f"{func.__name__} took {end_time - start_time} seconds to run.")
return result
return wrapper
# 使用裝飾器
@time_decorator
def long_running_function(number):
sum = 0
for i in range(number):
sum += i
return sum
# 調(diào)用函數(shù)
print(long_running_function(1000000))
在這個例子中,我們首先定義了一個名為 time_decorator 的裝飾器。 這個裝飾器接受一個函數(shù) func 作為參數(shù),并返回一個新的函數(shù) wrapper 。 wrapper 函數(shù)會記錄被裝飾的函數(shù)執(zhí)行前后的時間,從而計算出函數(shù)執(zhí)行所需的總時間,并打印出來。
然后,我們創(chuàng)建了一個long_running_function函數(shù),它接受一個參數(shù)并執(zhí)行一個簡單的累加操作。通過在這個函數(shù)前面添加@time_decorator,我們就把裝飾器應用到了long_running_function上。
當我們調(diào)用long_running_function(1000000)時,裝飾器會自動計算并打印出這個函數(shù)執(zhí)行所需的時間。這樣,我們就可以很容易地監(jiān)控任何函數(shù)的性能了。
總結(jié)
裝飾器是Python中一種非常強大的工具,它能夠幫助我們以非常優(yōu)雅的方式增強函數(shù)的功能,而不需要修改函數(shù)本身的代碼。
加我微信,送你 一份Python入門全套電子書。 微信: lzjun567 (備注: 資料)
