2016-11-04 19 views
0

私のクラス__setitem__を実装してクラスの属性を設定するにはどうすればよいですか?

class Base: 
    #has no attributes of its own 

    def __init__(self, params): 
     for key in params: 
      if hasattr(self, key): 
       self[key] = params[key] 

    def __setitem__(self, key, value): 
     self[key] = value 



class Child(Base): 
    prop1 = None 
    prop2 = None 

このしかし、self[key] = valueとして無限再帰に入るには、再帰的にself.__setitem__

私の目標は、この

params = dict(
    prop1 = "one", 
    prop2 = "two" 
) 
c = Child(params) 

c.prop1  #"one" 
c.prop2  #"two" 

ようChild()コンストラクタにAA辞書を渡すことができるようにすることですが呼び出されます子どものように多くの異なるクラスがありますが、フィールドは異なります。 paramsはjsonブロブからのdictです。私は、これがあろうと(私は、Pythonに新しいブランド午前)私は私が求めています何を達成するために内部dictを使用する方法を見てきましたが、それは私の理解されChild

のような異なるクラスのための一般的なポピュとしてBaseを使用したいですドット表記法を使用してメソッドにアクセスすることを防ぎます(これはむしろ避けたい)。

+1

与えられた 'hasattr'の要件は、あなたの提案よりも複雑です。子供の中にはいくつかのクラスレベル属性 'prop1'と' prop2'がありますが、 'field1'と' field2'を初期化しようとしていますが、これらは異なると思われますか? –

+0

クラス属性とインスタンス属性の違いを知っていますか? – martineau

+0

申し訳ありませんが、彼らは "propX"だったはずです。編集した – thedarklord47

答えて

2

ちょうどあなたの__init__内のインスタンスの__dict__を更新:

その後
class Base: 
    def __init__(self, params): 
     for key in params: 
      if hasattr(type(self), key): 
       self.__dict__[key] = params[key] 

class Child(Base): 
    field1 = None 
    field2 = None 

c = Child(dict(field1="one", field2="two", field3="three")) 

print(c.field1)  # "one" 
print(c.field2)  # "two" 
print(c.field3)  # => attr error 

孫は動作します:

class GrandChild(Child): 
    field3 = None 

gc = GrandChild(dict(field1="one", field2="two", field3="three")) 

print(gc.field1)  # "one" 
print(gc.field2)  # "two" 
print(gc.field3)  # "three" 
+0

これは '__slots__'では動作しませんでしたが、それはおそらくOPの必要性の範囲外です –

1

を私は何に想像できる最も近いです欲しいのは、setattrを使用することです。オブジェクト、属性名(strのような)、およびその属性の値を含む。

class Base(object): 
    def __init__(self, params): 
     for k, v in params.iteritems(): 
      if hasattr(self, k): 
       setattr(self, k, v) 

class Child(Base): 
    def __init__(self, params): 
     self.field1 = None # create attributes here, not at class level 
     self.field2 = None 
     Base.__init__(self, params) 

params = dict(
    field1 = "one", 
    field2 = "two", 
    field3 = "tree", # ignored when used with Child since it has no field3 
) 
c = Child(params) 
関連する問題