def decoratorA(arg):
def inner_decoratorA(cls):
print(f"Decorator A with arg: {arg} is decorating {cls.__name__}")
return cls
return inner_decoratorA
def decoratorB(arg):
def inner_decoratorB(cls):
print(f"Decorator B with arg: {arg} is decorating {cls.__name__}")
return cls
return inner_decoratorB
def decoratorC(arg):
def inner_decoratorC(cls):
print(f"Decorator C with arg: {arg} is decorating {cls.__name__}")
return cls
return inner_decoratorC
@decoratorA("string_arg")
@decoratorB(123)
@decoratorC({"key": "value"})
class MyAdvancedClass:
pass
- 执行顺序:
- 装饰器从下往上执行,即先执行
@decoratorC
,再执行 @decoratorB
,最后执行 @decoratorA
。
- 原因是装饰器的应用顺序与它们在类定义上方的排列顺序相反。Python 在解析类定义时,先遇到
@decoratorC({"key": "value"})
,此时会调用 decoratorC
函数并传入对象参数 {"key": "value"}
,返回一个内部装饰器函数 inner_decoratorC
,这个内部函数接收 MyAdvancedClass
作为参数进行装饰(此时只是返回了装饰后的类对象,还未完全构建 MyAdvancedClass
)。
- 接着遇到
@decoratorB(123)
,调用 decoratorB
函数并传入数字参数 123
,返回 inner_decoratorB
,inner_decoratorB
接收 inner_decoratorC
装饰后的 MyAdvancedClass
类对象进行装饰。
- 最后遇到
@decoratorA("string_arg")
,调用 decoratorA
函数并传入字符串参数 "string_arg"
,返回 inner_decoratorA
,inner_decoratorA
接收 inner_decoratorB
装饰后的 MyAdvancedClass
类对象进行装饰。
- 参数对装饰器行为的影响:
@decoratorA
:字符串参数 "string_arg"
可以用于装饰器内部的逻辑判断、日志记录等。例如,如果装饰器需要根据不同的字符串执行不同的增强逻辑,这个参数就起到关键作用。在上述代码中,只是简单打印了参数和被装饰类的信息。
@decoratorB
:数字参数 123
同样可以用于装饰器内部的逻辑,比如根据数字的大小决定是否对类进行特定的修改,或者用于计算某些与类相关的数值。在代码中也是简单打印展示。
@decoratorC
:对象参数 {"key": "value"}
为装饰器提供了更复杂的数据结构,可以基于对象的属性和方法进行各种操作。例如,根据对象的某个属性来修改类的属性或者方法等。在代码中同样只是简单打印展示。