在python中設置字典中的屬性
是否可以在python中從字典創建一個對象,使每個鍵都是該對象的屬性?
像這樣的東西:
d = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 }
e = Employee(d)
print e.name # Oscar
print e.age + 10 # 42
我認為這幾乎與這個問題相反:來自對象字段的Python字典
7個解決方案
124 votes
當然,這樣的事情:
class Employee(object):
def __init__(self, initial_data):
for key in initial_data:
setattr(self, key, initial_data[key])
更新
正如Brent Nash建議的那樣,您也可以通過允許關鍵字參數來使其更靈活:
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)
Ian Clelland answered 2019-04-26T17:51:53Z
35 votes
以這種方式設置屬性幾乎肯定不是解決問題的最佳方法。或者:
你知道所有領域應該提前做什么。 在這種情況下,您可以顯式設置所有屬性。 這看起來像
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
要么
你不知道所有領域應該提前做什么。 在這種情況下,您應該將數據存儲為dict而不是污染對象命名空間。 屬性用于靜態訪問。 這種情況看起來像
collections.namedtuple
另一個基本上與案例1相同的解決方案是使用collections.namedtuple.請參閱van的答案,了解如何實現這一點。
Mike Graham answered 2019-04-26T17:52:52Z
12 votes
您可以使用__dict__訪問對象的屬性,并在其上調用update方法:
>>> 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
Dave Kirby answered 2019-04-26T17:53:17Z
6 votes
如果你真的需要支持.name,我認為使用_asdict()的答案是可行的。
但是如果_asdict()對象只是一個可以使用點語法(.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()方法將所有屬性作為字典訪問,但以后只能在構造期間添加其他屬性。
van answered 2019-04-26T17:53:56Z
6 votes
為什么不直接使用屬性名作為字典的鍵?
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存儲類中使用的技巧)
RufusVS answered 2019-04-26T17:54:34Z
5 votes
比如說
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)
islam ezzat answered 2019-04-26T17:55:06Z
1 votes
類似于使用dict,你可以像這樣使用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'
Alex Spencer answered 2019-04-26T17:55:31Z