如何实现__setitem__来设置类的属性?

时间:2016-11-04 02:51:43

标签: python python-2.7 class dictionary

我的课程

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__

时,这会进入无休止的递归

我的目标是能够将字典传递到像这样的Child()构造函数

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

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

有很多不同的类,比如Child,但是有不同的字段。 params是来自json blob的字典。我想将Base用作Child

等不同类的通用填充符

我见过使用内部dict来完成我要求的方法,但我理解(我是Python新手)这会阻止通过点符号访问方法(我宁愿避免)。

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分: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)