Osc*_*Ryz 89 python attributes dictionary initialization properties
是否可以在python中从字典创建一个对象,使每个键都是该对象的属性?
像这样的东西:
d = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 }
e = Employee(d)
print e.name # Oscar
print e.age + 10 # 42
Run Code Online (Sandbox Code Playgroud)
我认为这几乎与这个问题相反:来自对象字段的Python字典
Ian*_*and 148
当然,这样的事情:
class Employee(object):
def __init__(self, initial_data):
for key in initial_data:
setattr(self, key, initial_data[key])
Run Code Online (Sandbox Code Playgroud)
更新
正如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])
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样调用它:
e = Employee({"name": "abc", "age": 32})
Run Code Online (Sandbox Code Playgroud)
或者像这样:
e = Employee(name="abc", age=32)
Run Code Online (Sandbox Code Playgroud)
或者甚至喜欢这样:
employee_template = {"role": "minion"}
e = Employee(employee_template, name="abc", age=32)
Run Code Online (Sandbox Code Playgroud)
Mik*_*ham 40
以这种方式设置属性几乎肯定不是解决问题的最佳方法.或者:
你知道所有领域应该提前做什么.在这种情况下,您可以显式设置所有属性.这看起来像
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
Run Code Online (Sandbox Code Playgroud)
要么
你不知道所有领域应该提前做什么.在这种情况下,您应该将数据存储为dict而不是污染对象命名空间.属性用于静态访问.这种情况看起来像
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
Run Code Online (Sandbox Code Playgroud)另一种基本上与案例1相同的解决方案是使用a collections.namedtuple.请参阅van的答案,了解如何实现这一点.
Dav*_*rby 13
您可以使用,访问对象的属性__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
Run Code Online (Sandbox Code Playgroud)
为什么不直接使用属性名作为字典的键?
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
Run Code Online (Sandbox Code Playgroud)
您可以使用命名参数,元组列表或字典或单个属性分配进行初始化,例如:
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)
Run Code Online (Sandbox Code Playgroud)
或者,您可以为未知值返回None,而不是引发属性错误.(web2py存储类中使用的技巧)
settattr如果您真的需要支持,我认为使用答案是可行的方法dict.
但是如果Employeeobject只是一个你可以使用dot syntax(.name)而不是dict syntax(['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'}
Run Code Online (Sandbox Code Playgroud)
你有_asdict()方法来访问所有属性的字典,但你不能只在施工以后添加附加属性.
比如说
class A():
def __init__(self):
self.x=7
self.y=8
self.z="name"
Run Code Online (Sandbox Code Playgroud)
如果要一次设置属性
d = {'x':100,'y':300,'z':"blah"}
a = A()
a.__dict__.update(d)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
69208 次 |
| 最近记录: |