我有一个装饰器类validatekeys()
和Node3D()
类。使用装饰器验证属性名称
的意图是用于Node3D
保持坐标的x,y的值,并且其使用的是@property
装饰检索Z,并且可以使用一个@coords.setter
装饰(它调用set_coords()
)或直接使用set_coords()
其本身的装饰被设置与validatekeys()
。我正在使用装饰器来完成此操作,以便以后可以添加其他类,例如Node2D()
。
代码:
class validatekeys(object):
def __init__(self,*keysIterable):
self.validkeys = []
for k in keysIterable:
self.validkeys.append(k)
def __call__(self,f):
def wrapped_f(*args,**kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
self.__dict__.update(kwargs)
return f(self,**kwargs)
return wrapped_f
class Node3D(object):
@property
def coords(self):
return self.__dict__
@coords.setter
def coords(self,Coords):
self.set_coords(**Coords)
@validatekeys('x','y','z')
def set_coords(self,**Coords):
pass
但是,并不如预期输出的一部分:
n = Node2D()
n.coords #{} <--expected
n.set_coords(x=1,y=2)
n.coords #{} <--not expected
n.set_coords(a=1,b=2) #Exception <--expected
它看起来像self.__dict__
没有被正确地更新。但是,我一直无法弄清楚如何解决这个问题。有什么建议么?
请注意,虽然我当然对解决这个问题的替代方案/方法感兴趣(验证输入给setter的键输入),但这主要是一个学习练习,以了解装饰器,类等的工作原理。
如果给'wrapped_f'一个明确的第一个参数,它需要有一个不同于验证器的名称,以避免对其进行遮蔽。它需要访问验证程序自身以检索存储在验证程序中而不是Node3D对象上的有效密钥列表。 – BrenBarn 2014-10-29 22:17:01
@BrenBarn:darn,在那里错过了'self.validkeys'。 – 2014-10-29 22:18:57
选择此为正确的答案,因为它绝对,肯定,清晰。谢谢。 – 2014-10-29 22:25:30