2011-10-17 7 views
3

クラスのインスタンスの属性をグループ化して、グループに属するすべての属性を繰り返し処理できるようにしたい。明らかな答えは、これらをすべてリストや辞書に入れることですが、私はオブジェクトの属性としてアクセスすることができず、私はそれを好むでしょう。エレガントなグループ化属性

一部のコードでは、わたしが望むものを明確にする必要があります。ここには実際にリストと実際の属性があります。 rotate()を呼び出すとき

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') 

今では回転するベクトル何を知っていると私は動的にそのリストに複数のベクトルを追加することができます。しかし、これは仕事ではありますが、自分でリストを管理しなければならないので、それは私にはエレガントではありません。

これを書く簡単な方法はありますか?私はすべての属性を辞書に格納することを考えました。ここで各グループはキーであり、次にproperties()を使用して辞書のすべての項目に属性としてアクセスできます。それは私のために十分にきれいになりますが、メソッド内でプロパティを動的に設定する方法はわかりません。

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

そして簡単に値にアクセスするpropertiesを使用します:rotatableVectorクラスの属性にする方法について

+2

、あなたは 'v1'という名前の属性を持っている場合は、 'v2'、...、' vn'、おそらくあなたのデザインに何か問題があります。 'obj.vectors [0]'などとしてアクセスする際に何が問題になりますか? – geoffspear

+1

この例では、解はdef rotate_vectors(angle、* vectors)です:return [do_rotate(vector、vector in vector)] '。クラスの使用は愚かです。 –

+0

よろしいですか。このクラスは、私の実際のコードを単純化したものです。私の実際のコードでは、すべてのベクトルの説明的な名前があり、クラスはこれより複雑です。私は関連性のある部分を抽出しました。 –

答えて

3

一般に
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 = rotatable'を意味するとします。ちょうどそれのために 'namedtuple'を使うことができます。 – 9000

+0

@ 9000:訂正してくれてありがとうございます( 'self.rotatable = rotatable')。 'vector.value'の値が変わるのでここでは' namedtuple'を使用しません。 'namedtuple'でそれを行うには、privateメソッド' _replace'を呼び出す必要があります。 – unutbu

関連する問題