Python中的Decorator函数
Python中的装饰器(Decorator)是一种特殊的函数,可以修改其他函数的行为。它可以在不修改原函数代码的情况下,添加额外的功能,例如:记录日记、计时、身份验证、缓存等等。
一、装饰器的基本用法
使用 python 装饰器,就可以把对函数的修饰看作是一个函数,那么它实际上是一个接受函数返回一个函数的高阶函数。常见的装饰器有很多种,比较常见的如下。
1. 函数装饰器
示例如下:
def func_decorator(func):
def wrapper(*args, **kwargs):
# Do something before the function is called
print("do something before the function is called")
# Call the function
result = func(*args, **kwargs)
# Do something after the function is called
print("do something after the function is called")
return result
return wrapper
@func_decorator
def my_function(x, y):
return x + y
my_result = my_function(2, 3)
print(my_result) # output: 5
解释:
该示例中,我们定义了一个装饰器函数 func_decorator,接受一个函数作为输入,并返回一个新的函数。新的函数 wrapper 在原函数 my_function 调用时会被执行,因为我们在 my_function 上添加了 @func_decorator 装饰器。这就相当于把 my_function 函数传递给了 func_decorator,因此 wrapper 函数所执行的内容就会在 my_function 中执行。
在该示例的 wrapper 函数中,我们首先添加了 “do something before the function is called” 的语句,然后调用了原本的函数,并把结果保存到变量 result 中。最后输出了一个带有 “do something after the function is called” 字符串的语句,并返回了计算的结果。
2. 类装饰器
类装饰器采用相同的逻辑,只是翻译成了类方法。
示例如下:
class ClassDecorator(object):
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
print("do something before the function is called")
result = self.f(*args, **kwargs)
print("do something after the function is called")
return result
@ClassDecorator
def my_function(x, y):
return x + y
my_result = my_function(2, 3)
print(my_result) # output: 5
解释:
该示例中,我们定义了一个类 ClassDecorator,它接受一个函数作为输入,并存储在 __init__ 函数中。在调用过程中,我们在 __call__ 方法中添加了所需的代码,并调用保存的函数。
然后,我们在 my_function 函数上添加了 @ClassDecorator 装饰器,这会把我们的 my_function 函数传递给 ClassDecorator 类的实例化对象。此时 my_function 会被替换为一个调用 ClassDecorator 实例的 __call__ 方法的新对象。因此,新对象在执行 my_function 时,会在执行前后执行我们自定义的方法。
II. 装饰器的应用
装饰器的应用有很多,其中最常见的应用是在函数上添加日志记载、计时、数据验证、缓存等功能。下面介绍一些常见的装饰器。
1. 计时器装饰器
计时器装饰器可以用于评估函数的性能。例如,我们可以用这个装饰器计算某个函数的执行时间。
示例如下:
import time
def timer(func):
def wrapper(*args, **kwargs):
t1 = time.time()
result = func(*args, **kwargs)
t2 = time.time()
print(f'{func.__name__} took {t2-t1} seconds to execute')
return result
return wrapper
@timer
def my_function(x, y):
time.sleep(2)
return x + y
result = my_function(2, 3)
解释:
在这个例子中, timer 装饰器接受一个函数作为输入,并定义一个名为 wrapper 的内部函数。 wrapper 函数首先记录了起始时间,执行函数,然后记录结束时间。输出结果表明,该函数的执行时间大约为2秒。
2. 日志记录装饰器
日志记录装饰器可以用于在函数执行期间记录日志。这在调试代码或记录函数执行的详细信息时非常有用。
示例如下:
import logging
logging.basicConfig(level=logging.INFO)
def logger(func):
def wrapper(*args, **kwargs):
logging.info(f'[INFO] Function "{func.__name__}" was called with args: {args}, {kwargs}')
result = func(*args, **kwargs)
logging.info(f'[INFO] Result: {result}')
return result
return wrapper
@logger
def my_function(x, y):
return x + y
my_function(2, 3)
解释:
在这个例子中, logger 装饰器定义了一个内部函数 wrapper,用于实现日志记录功能。在执行函数时,我们可以使用 logging 模块记录执行信息。
在这个示例中, logger 装饰器添加了函数被调用信息和函数执行结果的日志记录。运行该程序会输出以下结果:
INFO:root:[INFO] Function "my_function" was called with args: (2, 3), {}
INFO:root:[INFO] Result: 5
3. 缓存装饰器
缓存装饰器可以用于存储函数的计算结果,并在下次调用时使用已存储的结果,以提高代码效率。
示例如下:
def memoize(func):
cache = {}
def wrapper(*args):
if args in cache:
return cache[args]
else:
result = func(*args)
cache[args] = result
return result
return wrapper
@memoize
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
解释:
在这个示例中,我们定义了一个 memoize 装饰器。 wrapper 函数首先检查缓存中是否有输入参数的结果。如果结果已经缓存,则返回缓存的结果,否则计算结果并将它添加到缓存中。
fibonacci 函数使用 memoize 装饰器,这意味着在调用 fibonacci 函数时,会先检查缓存中是否有结果。
4. 身份验证装饰器
身份验证装饰器可以用于验证用户的身份,通常被用于一些敏感操作,例如:删除、修改、新增等操作。
示例如下:
def authenticated(func):
def wrapper(*args, **kwargs):
if is_authenticated_user():
result = func(*args, **kwargs)
return result
else:
return 'You must be authenticated to access this function!'
return wrapper
@authenticated
def my_function():
return 'This function requires authentication'
print(my_function())
解释:
在这个示例中,我们定义了一个 authenticated 装饰器。 wrapper 函数首先检查用户是否验证并通过身份验证后,才调用原始函数。
my_function 函数使用 authenticated 装饰器,这意味着在调用 my_function 函数时,会先检查用户是否验证通过。
总结:
Python中的Decorator函数适用于在不修改原函数代码的情况下为函数添加额
