我有一個裝飾器類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