2011-10-17 54 views
3

我想將一個類的實例的屬性分組,以便遍歷屬於一個組的所有屬性。顯而易見的答案是將所有這些放在一個列表或字典中,但是我不能將它們作爲我的對象的屬性訪問,我寧願這樣做。優雅的分組屬性方法

有些代碼應該清楚我想要什麼。這裏我實際上有一個列表和真正的屬性。現在

class Vectors(object): 

    def __init__(self, v1, v2, v3): 
     self.v1 = v1 
     self.v2 = v2 
     self.v3 = v3 
     self.rotatable = ['v2', 'v3'] 

    def rotate(self, angle): 
     for v in self.rotable: 
      new_vector = do_rotate(getattr(self, v), angle) 
      setattr(self, v, new_vector) 

class MoreVectors(Vectors): 
    def __init__(self, v4, *args, **kwargs): 
     super(MoreVectors, self).__init__(*args, **kwargs) 
     self.v4 = v4 
     self.rotable.append('v4') 

調用rotate()當它知道什麼矢量旋轉,我可以動態地向列表中添加更多的載體。然而,雖然這樣做的確如此,但我看起來並不那麼優雅,因爲我必須自己管理清單。

有沒有一些簡單的方法來寫這個?我考慮將所有屬性存儲在字典中,其中每個組都是一個關鍵字,然後使用properties()來讓我訪問字典的所有項目作爲屬性。這對我來說足夠乾淨,但我不知道如何在方法內動態設置屬性。

+2

一般情況下,如果有一個名爲屬性'v1', 'v2',...,'vn',你的設計可能有問題。以「obj.vectors [0]」等方式訪問有什麼問題? – geoffspear

+1

在這個例子中,解決方案是'def rotate_vectors(angle,* vectors):return [向量中的do_rotate(vector,angle)]。使用課堂是愚蠢的。 –

+0

好的。這個類僅僅是我真正的代碼的簡化。在我的真實代碼中,我確實有所有向量的描述性名稱,而類比這更復雜。我剛剛提取了相關的部分。 –

回答

3

如何讓rotatable一個Vector類的屬性:

class Vector(object): 
    def __init__(self,v,rotatable=False): 
     self.value = v 
     self.rotatable = rotatable 

然後用properties輕鬆訪問值:

class Vectors(object): 
    def __init__(self, v1, v2, v3): 
     self.vectors = [Vector(v1),Vector(v2,rotatable=True),Vector(v3,rotatable=True)] 
    @property 
    def v1(self): 
     return self.vectors[0].value 
    @property  
    def v2(self): 
     return self.vectors[1].value 
    @property  
    def v3(self): 
     return self.vectors[2].value 
    def rotate(self, angle): 
     for vector in self.vectors: 
      if vector.rotatable: 
       vector.value = do_rotate(vector.value, angle) 

class MoreVectors(Vectors): 
    def __init__(self, v4, *args, **kwargs): 
     super(MoreVectors, self).__init__(*args, **kwargs) 
     self.vectors.append(Vector(v4,rotatable=True)) 
    @property 
    def v4(self): 
     return self.vectors[3].value 
+0

我想你在'Vector'的構造函數中的意思是'self.rotatable = rotating'。順便說一句,你可以爲它使用'namedtuple'。 – 9000

+0

@ 9000:感謝您的更正('self.rotatable =可旋轉')。這裏我不會使用'namedtuple',因爲'vector.value'的值會改變。用'namedtuple'這樣做需要調用私有方法'_replace'。 – unutbu