Использование декораторов в качестве атрибутов класса вместо атрибутов экземпляра

У меня есть следующие классы.

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 .

РЕДАКТИРОВАТЬ: ЭТО НЕПРАВИЛЬНО ! См. Ответ ниже.

Обратите внимание, что это прежде всего учебное упражнение для меня, и хотя мне было бы интересно услышать критику / предложения по улучшению моего подхода, я должен прежде всего узнать, как эффективно использовать декораторов.

Также обратите внимание, что я обычно не использовал бы капитализацию для класса декоратора, но я использую его здесь, так как это облегчает чтение на SO.

Мое предположение было неверным.

Поскольку все написано, для каждого класса создается только один экземпляр Validator и ValidateKeys . Я не понимал, что строка @Validator(ValidateKeys, 'x','y') работает только один раз (во время определения класса), а не при создании экземпляра.

Я должен был это осознать, поскольку выражения декоратора появляются на том же уровне иерархии, что и атрибуты класса , например:

 class MyClass(): class_attribute = None #only one class_attribute is created @decorator #only one decorator (ie, 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}' 

У меня нет такой проблемы, как я думал. Спасибо всем за помощь.