与作为函数的装饰器相比,装饰器的限制为 class
Limit of decorator as class compared to decorator as function
我想确保我正确理解装饰器 class 的工作原理。
假设我有一个装饰器作为向对象添加属性的函数
def addx(obj):
obj.x = 10
return obj
@addx
class A:
pass
assert A.x == 10
是否可以编写与 class 装饰器相同的装饰器?因为 class 装饰器不能 return 对象本身 __init__
class addx:
def __init__(self, obj):
obj.x = 10
# ???
你可以像这样写一个等效的基于 class 的装饰器...
class addx:
def __new__(self, obj):
obj.x = 10
return obj
@addx
class A:
pass
assert A.x == 10
...但我认为这对您没有任何帮助。当您的目标是修改 class A
的对象而不是 class A
本身时,基于 class 的装饰器的实用性变得更加明显。比较以下两个装饰器,一个基于函数,一个基于 class:
def addx_func(kls):
def wrapper():
res = kls()
res.x = 10
return res
return wrapper
class addx_class:
def __init__(self, kls):
self.kls = kls
def __call__(self):
res = self.kls()
res.x = 10
return res
@addx_func
class A:
pass
@addx_class
class B:
pass
a = A()
assert a.x == 10
b = B()
assert b.x == 10
我想确保我正确理解装饰器 class 的工作原理。
假设我有一个装饰器作为向对象添加属性的函数
def addx(obj):
obj.x = 10
return obj
@addx
class A:
pass
assert A.x == 10
是否可以编写与 class 装饰器相同的装饰器?因为 class 装饰器不能 return 对象本身 __init__
class addx:
def __init__(self, obj):
obj.x = 10
# ???
你可以像这样写一个等效的基于 class 的装饰器...
class addx:
def __new__(self, obj):
obj.x = 10
return obj
@addx
class A:
pass
assert A.x == 10
...但我认为这对您没有任何帮助。当您的目标是修改 class A
的对象而不是 class A
本身时,基于 class 的装饰器的实用性变得更加明显。比较以下两个装饰器,一个基于函数,一个基于 class:
def addx_func(kls):
def wrapper():
res = kls()
res.x = 10
return res
return wrapper
class addx_class:
def __init__(self, kls):
self.kls = kls
def __call__(self):
res = self.kls()
res.x = 10
return res
@addx_func
class A:
pass
@addx_class
class B:
pass
a = A()
assert a.x == 10
b = B()
assert b.x == 10