2016-11-04 23 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__

我的目標是能夠通過AA字典爲Child()構造這樣

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

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

有許多不同的類,像Child,但有不同的字段。 params是來自json blob的字典。我想用Base作爲通用填充器的不同類,如Child

我已經看到了使用內部dict來完成我要問的方法,但它是我的理解(我的品牌新的Python),這將阻止通過點符號訪問方法(我寧願避免)。

+1

考慮到'hasattr',你的要求比你的建議更復雜。在孩子的內部,你有一些類級別的屬性'prop1'和'prop2',但試圖初始化'field1'和'field2',這些應該是不同的? –

+0

你知道類和實例屬性之間的區別嗎? – martineau

+0

對不起,他們應該是「propX」。編輯 – thedarklord47

回答

2

剛剛更新實例的__dict____init__

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,其中ta kes一個對象,一個屬性名稱(作爲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)