gpt4 book ai didi

python - 使用装饰器作为类属性而不是实例属性

转载 作者:太空宇宙 更新时间:2023-11-04 03:40:34 26 4
gpt4 key购买 nike

我有以下类(class)。

Validator 是一个装饰器,它接收一个定义装饰函数验证标准的类。 ValidateKeys 是这个例子的验证标准。 Node2D 是一个使用验证标准的类。

class Validator(object):
def __init__(self, TheValidator, *args, **kwargs):
self.validator = TheValidator(*args,**kwargs)
def __call__(self,f):
def wrapped_f(instance, *args,**kwargs):
self.TheValidator(instance, *args, **kwargs)
return f(instance,*args,**kwargs)
return wrapped_f

class ValidateKeys(object):
def __init__(self,*keysIterable):
self.validkeys = keysIterable
def __call__(self, instance, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance.__dict__.update(kwargs)

class Node2D(object):
@property
def coords(self):
return self.__dict__
@coords.setter
def coords(self,Coords):
self.set_coords(**Coords)
@Validator(ValidateKeys, 'x','y')
def set_coords(self,**Coords):
pass

据我所知,正如这里所写的那样,Node2D 的每个实例都将生成一个重复的 Validator(任何其他用 Validator< 装饰的类也是如此) 和 ValidateKeys

编辑:THIS IS WRONG ! 请参阅下面的答案。

请注意,这对我来说主要是一个学习练习,虽然我有兴趣听取批评/建议以改进我的整体方法,但我的主要目标是了解更多有关如何有效使用装饰器的信息。

另请注意,我通常不会对装饰器类使用大写,但在这里使用它是因为它更易于阅读 SO。

最佳答案

我的假设是错误的。

根据编写的内容,每个类仅创建一个 ValidatorValidateKeys 实例。我没有意识到行 @Validator(ValidateKeys, 'x','y') 只运行一次(在类定义时)而不是在实例创建时。

应该意识到这一点,因为装饰器表达式出现在与 class attributes 相同的层次结构级别,例如:

class MyClass():
class_attribute = None #only one class_attribute is created
@decorator #only one decorator (i.e., decorated method) is created
def method():
pass

测试:

class Validator(object):
def __init__(self, TheValidator, *args, **kwargs):
print("New Validator Object")
self.TheValidator = TheValidator(*args,**kwargs)
def __call__(self,f):
def wrapped_f(instance, *args,**kwargs):
self.TheValidator(instance, *args, **kwargs)
return f(instance,*args,**kwargs)
return wrapped_f

class ValidateKeys(object):
def __init__(self,*keysIterable):
print("New ValidateKeys Object")
self.validkeys = keysIterable
def __call__(self, instance, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance.__dict__.update(kwargs)

class Node2D(object):
@property
def coords(self):
return self.__dict__
@coords.setter
def coords(self,Coords):
self.set_coords(**Coords)
@Validator(ValidateKeys, 'x','y')
def set_coords(self,**Coords):
pass

n1 = Node2D()
n2 = Node2D()
n1.setcoords(x=1,y=2)
n1.coords

输出:

'New Validator Object'    #<-- Seen only once when module is loaded (class defined)
'New ValidateKeys Object' #<-- Seen only once when module is loaded (class defined)
'{'x': 1, 'y': 2}'

我没有遇到我认为的问题。感谢大家的帮助。

关于python - 使用装饰器作为类属性而不是实例属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26653422/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com