在python中设置字典的属性
是否有可能从一个字典在Python中创build一个对象,使每个键是该对象的属性?
像这样的东西:
d = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 } e = Employee(d) print e.name # Oscar print e.age + 10 # 42 我认为这几乎是这个问题的反面: 来自对象字段的Python字典
当然,这样的事情:
 class Employee(object): def __init__(self, initial_data): for key in initial_data: setattr(self, key, initial_data[key]) 
更新
正如布伦特·纳什(Brent Nash)所build议的那样,通过允许关键字参数,也可以使其更加灵活
 class Employee(object): def __init__(self, *initial_data, **kwargs): for dictionary in initial_data: for key in dictionary: setattr(self, key, dictionary[key]) for key in kwargs: setattr(self, key, kwargs[key]) 
那么你可以这样调用它:
 e = Employee({"name": "abc", "age": 32}) 
或者像这样:
 e = Employee(name="abc", age=32) 
甚至像这样:
 employee_template = {"role": "minion"} e = Employee(employee_template, name="abc", age=32) 
以这种方式设置属性几乎肯定不是解决问题的最佳方法。 或者:
- 
你知道所有的领域应该提前。 在这种情况下,你可以明确地设置所有的属性。 这看起来像 class Employee(object): def __init__(self, name, last_name, age): self.name = name self.last_name = last_name self.age = age d = {'name': 'Oscar', 'last_name': 'Reyes', 'age':32 } e = Employee(**d) print e.name # Oscar print e.age + 10 # 42要么 
- 
你不知道所有的领域应该提前。 在这种情况下,您应该将数据存储为字典而不是污染对象名称空间。 属性用于静态访问。 这种情况看起来像 class Employee(object): def __init__(self, data): self.data = data d = {'name': 'Oscar', 'last_name': 'Reyes', 'age':32 } e = Employee(d) print e.data['name'] # Oscar print e.data['age'] + 10 # 42
 基本上等同于情况1的另一个解决scheme是使用collections.namedtuple 。 请参阅van的回答,了解如何实现这一点。 
 你可以用__dict__来访问一个对象的属性,并调用它的更新方法: 
 >>> class Employee(object): ... def __init__(self, _dict): ... self.__dict__.update(_dict) ... >>> dict = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 } >>> e = Employee(dict) >>> e.name 'Oscar' >>> e.age 32 
为什么不使用属性名称作为字典的关键字?
 class StructMyDict(dict): def __getattr__(self, name): try: return self[name] except KeyError as e: raise AttributeError(e) def __setattr__(self, name, value): self[name] = value 
您可以使用命名参数,元组列表或字典或个别属性分配进行初始化,例如:
 nautical = StructMyDict(left = "Port", right = "Starboard") # named args nautical2 = StructMyDict({"left":"Port","right":"Starboard"}) # dictionary nautical3 = StructMyDict([("left","Port"),("right","Starboard")]) # tuples list nautical4 = StructMyDict() # fields TBD nautical4.left = "Port" nautical4.right = "Starboard" for x in [nautical, nautical2, nautical3, nautical4]: print "%s <--> %s" % (x.left,x.right) 
或者,不是提高属性错误,而是为未知值返回None。 (在web2py存储类中使用的一个技巧)
 我认为,如果你真的需要支持dict那么使用settattr答案是要走的路。 
 但是,如果Employee对象只是一个你可以用点语法( .name )而不是dict语法( ['name'] )访问的结构体,那么你可以像这样使用namedtuple : 
 from collections import namedtuple Employee = namedtuple('Employee', 'name age') e = Employee('noname01', 6) print e #>> Employee(name='noname01', age=6) # create Employee from dictionary d = {'name': 'noname02', 'age': 7} e = Employee(**d) print e #>> Employee(name='noname02', age=7) print e._asdict() #>> {'age': 7, 'name': 'noname02'} 
 你有_asdict()方法来作为字典来访问所有的属性,但是以后只能在构build过程中不能添加其他的属性。 
比如说
 class A(): def __init__(self): self.x=7 self.y=8 self.z="name" 
如果你想一次设置属性
 d = {'x':100,'y':300,'z':"blah"} a = A() a.__dict__.update(d) 
类似于使用字典,你可以像这样使用kwargs:
 class Person: def __init__(self, **kwargs): self.properties = kwargs def get_property(self, key): return self.properties.get(key, None) def main(): timmy = Person(color = 'red') print(timmy.get_property('color')) #prints 'red'