Python中的装饰器函数详解
装饰器是Python中一个非常有用的概念,可以用于给函数或类添加额外的功能。实际上,装饰器本身也是一个函数,它接受一个函数作为参数,并返回一个新的函数。这个新的函数通常会在原有函数的基础上添加一些额外的功能,如打印日志、计时、权限验证等。
装饰器的语法比较简单,就是在要装饰的函数的定义之前加上一个@符号,后面紧跟着装饰器函数的名称。例如:
@decorator
def func():
pass
下面我们来详细了解一下装饰器的使用。
装饰器函数的定义方式如下:
def decorator(func):
def wrapper(*args, **kwargs):
# 添加额外的功能
return func(*args, **kwargs)
return wrapper
装饰器函数接受一个函数作为参数,并返回一个新的函数。新的函数通常会在原有函数的基础上添加一些额外的功能,这些功能写在新函数内部。
新函数的参数可以根据原有函数的参数来定义,通常使用*args和**kwargs表示任意数量的位置参数和关键字参数。
最后,装饰器函数要返回新函数wrapper。
下面我们来看一个具体的例子。
def log(func):
def wrapper(*args, **kwargs):
print(f"Calling function {func.__name__}")
return func(*args, **kwargs)
return wrapper
@log
def add(a, b):
return a + b
使用@log装饰器来给add函数添加打印日志的功能。当我们调用add函数时,会自动打印出函数名。
add(1, 2)
# Output: Calling function add
装饰器函数可以添加多个装饰器,多个装饰器按照从上到下的顺序依次执行。
例如,我们可以添加一个计时器装饰器:
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} elapsed time: {end_time - start_time}s")
return result
return wrapper
@log
@timer
def add(a, b):
return a + b
使用@log和@timer装饰器来给add函数添加打印日志和计时的功能。当我们调用add函数时,会自动打印出函数名和运行时间。
add(1, 2)
# Output:
# Calling function add
# Function add elapsed time: 1.2e-05s
装饰器还可以接受参数,通过在装饰器函数之上再定义一个函数来接收参数,并返回一个装饰器函数。
例如,我们可以定义一个带有参数的装饰器函数,用于指定需要打印的日志级别:
def log(level):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"[{level}] Calling function {func.__name__}")
return func(*args, **kwargs)
return wrapper
return decorator
@log("INFO")
def add(a, b):
return a + b
使用@log("INFO")装饰器来给add函数添加打印INFO级别的日志。当我们调用add函数时,会自动打印出INFO级别的日志。
add(1, 2)
# Output: [INFO] Calling function add
最后,装饰器还可以用于类。同样的语法,在类的定义之前加上一个@符号,后面紧跟着装饰器函数的名称。
例如,我们可以定义一个用于验证用户权限的装饰器:
def access_control(func):
def wrapper(self, *args, **kwargs):
if self.logged_in:
return func(self, *args, **kwargs)
else:
raise Exception("Access denied")
return wrapper
class Calculator:
def __init__(self):
self.logged_in = False
@access_control
def add(self, a, b):
return a + b
使用@access_control装饰器来给add方法添加权限验证的功能。当我们调用add方法时,会先检查用户是否已登录,如果已登录则执行原有的add方法,否则抛出异常。
calculator = Calculator()
calculator.logged_in = True
calculator.add(1, 2)
# Output: 3
装饰器是Python中非常有用的特性,可以帮助我们在不修改原有代码的情况下添加功能。通过使用装饰器,我们可以实现代码的复用和组合,提高代码的可读性和可维护性。
