2016-11-04 43 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)