python使用自定义注解类和装饰器来实现函数的额外行为
class CustomAnnotation:
def __init__(self, arg1="default1", arg2="default2"):
self.arg1 = arg1
self.arg2 = arg2
def __call__(self, func):
# 将注解附加到函数中
func.__custom_annotation__ = {'arg1': self.arg1, 'arg2': self.arg2}
return func
def process_annotation(func):
def wrapper(*args, **kwargs):
# 获取 CustomAnnotation 添加的注解
annotation = getattr(func, '__custom_annotation__', None)
if annotation:
print(f"Annotation values: {annotation['arg1']}, {annotation['arg2']}")
return func(*args, **kwargs)
return wrapper
@process_annotation
@CustomAnnotation() # 不提供参数,将使用默认值 "default1" 和 "default2"
def my_function_default():
"""
这是一个使用默认参数的示例函数
"""
print("Executing my_function_default")
@process_annotation
@CustomAnnotation("custom1", "custom2") # 提供自定义值
def my_function_custom():
"""
这是一个使用自定义参数的示例函数
"""
print("Executing my_function_custom")
my_function_default()
my_function_custom()
这段代码展示了如何使用自定义注解类和装饰器来实现函数的额外行为。下面是这段代码的详细解释:
1. CustomAnnotation
类
-
初始化方法 (
__init__
):arg1
和arg2
是构造函数的参数,用于初始化CustomAnnotation
对象。- 这些参数被保存在实例的属性
self.arg1
和self.arg2
中。
-
调用方法 (
__call__
):__call__
方法使得CustomAnnotation
实例可以像装饰器一样被调用。- 当
CustomAnnotation
被用作装饰器时,它用来接收被装饰的函数func
。 - 在函数对象
func
上,附加一个新的属性__custom_annotation__
,它是一个字典,包含键'arg1'
和'arg2'
,值分别是self.arg1
和self.arg2
。 - 最后,返回被装饰的函数
func
。
2. process_annotation
函数
-
装饰函数
func
:- 这是一个装饰器函数,它装饰另一个函数,称为
func
。
- 这是一个装饰器函数,它装饰另一个函数,称为
-
内层函数
wrapper
:- 这是一个包装函数,用来替代并增强装饰的函数
func
。 - 在
wrapper
内部,通过getattr
函数尝试获取func
上的__custom_annotation__
属性。 - 如果该属性存在,这意味着
func
确实被CustomAnnotation
装饰了,它将打印出附加的注解值。 - 最后,它调用并返回原始函数
func
的结果。
- 这是一个包装函数,用来替代并增强装饰的函数
3. 函数和装饰器的使用
@process_annotation
@CustomAnnotation("value1", "value2")
def my_function():
"""
这是一个示例函数
"""
print("Executing my_function")
my_function
函数首先被CustomAnnotation("value1", "value2")
装饰。这意味着在my_function
上附加了__custom_annotation__
属性。- 然后,
my_function
被process_annotation
装饰。这个装饰器会创建一个包装函数wrapper
,它会在调用my_function
之前打印注解信息。
4. 调用 my_function
- 当调用
my_function()
时,实际执行的是process_annotation
装饰器的wrapper
函数。 wrapper
首先检查并打印出my_function
上的注解值 “value1” 和 “value2”。- 然后,它执行
my_function
的原始逻辑,即打印 “Executing my_function”。
输出
调用 my_function()
会输出:
Annotation values: value1, value2
Executing my_function
这表明装饰器成功地在执行函数的主逻辑之前对其进行了增强。