Python @使用详解
1.介绍
在Python中,@
符号被称为装饰器(Decorator)。装饰器是一种用来修改函数或类的行为的函数(或类)。它们提供了一种简洁而优雅的方式来修改函数或类的功能,而不需要直接修改它们的代码。
装饰器本质上是一个 Python 函数或类,它可以接受一个函数或类作为参数,并返回一个新的函数或类。使用装饰器可以在不更改原始函数或类定义的情况下,添加一些额外的功能、修改或封装原始函数或类。
装饰器的应用非常广泛,常用于代码重用、注入额外逻辑、实现AOP(面向切面编程)等方面。
本文将详细介绍Python中装饰器的使用方法、常见应用场景以及一些实际示例。
2.装饰器基础
2.1.函数装饰器
函数装饰器是最常见的装饰器形式。一个函数装饰器接受一个函数作为参数,并返回一个新的函数。新的函数通常会在原始函数的基础上添加一些额外的逻辑。
下面是一个简单的示例来说明如何创建一个函数装饰器:
def decorator_function(func):
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@decorator_function
def hello():
print("Hello, world!")
hello()
输出结果:
Before function execution
Hello, world!
After function execution
在上面的示例中,我们定义了一个名为decorator_function
的函数装饰器。该装饰器接受一个函数作为输入参数,并返回一个新的函数wrapper
。新的函数wrapper
在执行原始函数func
之前和之后输出一些额外的文本。
通过在函数定义的上方添加@decorator_function
,我们将decorator_function
应用到了hello
函数上。这样一来,当我们调用hello
函数时,实际上是在调用wrapper
函数。
2.2.类装饰器
除了函数装饰器,Python中还支持类装饰器。类装饰器是一个类,它可以接受一个函数或类作为参数,并返回一个新的函数或类。
下面是一个示例来说明如何创建一个类装饰器:
class DecoratorClass:
def __init__(self, func):
self.func = func
def __call__(self):
print("Before function execution")
self.func()
print("After function execution")
@DecoratorClass
def hello():
print("Hello, world!")
hello()
输出结果与上面的函数装饰器示例相同。
在上面的示例中,我们定义了一个名为DecoratorClass
的类装饰器。类装饰器需要实现__init__
和__call__
方法。__init__
方法在实例化类装饰器时被调用,并接受被装饰函数作为参数。__call__
方法在调用被装饰函数时被调用。
通过将DecoratorClass
应用到hello
函数上,我们实际上是在创建一个DecoratorClass
的实例,并将其作为函数调用。
3.常见装饰器应用场景
装饰器在实际开发中有着广泛的应用,以下是一些常见的应用场景:
3.1.日志记录
装饰器可以用于实现函数或类的调用日志记录,方便调试和追踪程序运行时的流程。
下面是一个简单的示例来说明如何使用装饰器记录函数调用的日志:
import logging
def log_function_call(func):
def wrapper(*args, **kwargs):
logging.info(f"Calling function {func.__name__} with args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
logging.info(f"Function {func.__name__} returned result: {result}")
return result
return wrapper
@log_function_call
def add(a, b):
return a + b
result = add(1, 2)
在上面的示例中,我们定义了一个名为log_function_call
的装饰器,它会在函数调用前后记录相关信息。通过在add
函数的定义上方添加@log_function_call
,我们就可以方便地记录函数的调用过程。
3.2.性能分析
装饰器还可以用于实现函数的性能分析,包括函数的运行时间、内存占用等指标的统计。
下面是一个简单的示例来说明如何使用装饰器实现性能分析:
import time
def profile_function(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
execution_time = end_time - start_time
print(f"Function {func.__name__} took {execution_time} seconds to execute")
return result
return wrapper
@profile_function
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
result = fibonacci(10)
在上面的示例中,我们定义了一个名为profile_function
的装饰器,它会在函数执行前后计算函数的执行时间。通过在fibonacci
函数的定义上方添加@profile_function
,我们就可以方便地统计函数的执行时间。
3.3.权限验证
装饰器还可以用于实现权限验证,例如检查用户是否有访问某个资源的权限。
下面是一个简单的示例来说明如何使用装饰器实现权限验证:
def check_permission(permission):
def decorator(func):
def wrapper(*args, **kwargs):
if check_user_permission(permission):
return func(*args, **kwargs)
else:
raise PermissionError("You do not have permission to access this resource")
return wrapper
return decorator
@check_permission("admin")
def delete_resource(resource_id):
# 删除资源的逻辑
pass
delete_resource("resource_123")
在上面的示例中,我们定义了一个名为check_permission
的装饰器工厂函数,它接受一个权限参数,并返回一个装饰器。装饰器在函数调用前检查用户的权限,如果有权限则继续执行函数,否则抛出权限错误。
通过在delete_resource
函数的定义上方添加@check_permission("admin")
,我们就可以方便地验证用户是否具有删除资源的权限。