各キーがそのオブジェクトの属性になるようにPythonの辞書からオブジェクトを作成することは可能ですか?
このようなもの:
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が示唆しているように、キーワード引数を許可することでこれをより柔軟にすることができます。
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)
def __init__(self,**initial_data)
キーワード引数も使用できるinitメソッド(例:" e = Employee(name ='オスカー">" 39")または辞書に取り込む(例:" e =")という利点があります。従業員(**辞書)")。 - Brent Writes CodeEmployee(some_dict)
そしてそのEmployee(**some_dict)
APIが矛盾しています。どちらか良い方を指定してください。 - Mike Graham()
の代わりにNone
そう、あなたはそうすることができます:def __init__(self, iterable=(), **kwargs): self.__dict__.update(iterable, **kwargs)
。 - Matt Anderson[[setattr(self,key,d[key]) for key in d] for d in some_dict]
- T.Z.AddressNotFoundError
'(その場合は修正するのではなく、修正したデータを返すために) - PHPでは非常に簡単なことに夢中になっていた((object) ['x' => 'y']
)Pythonではそれほど多くのことが必要 - Someguy123
このように属性を設定することは、ほとんど確実に問題を解決するための最良の方法ではありません。どちらか
あなたはすべての分野が前もってあるべきであることを知っています。その場合は、すべての属性を明示的に設定できます。これは次のようになります
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と基本的に同等のもう1つの解決策は、collections.namedtuple
。実装方法についてはvanの回答を参照してください。
オブジェクトの属性にアクセスすることができます__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
__dict__
実装成果物であり、使用しないでください。また、これはクラス上の記述子の存在を無視します。 - Ignacio Vazquez-Abrams__dict__
実装成果物ではなく、言語の文書化された部分です。 - Dave Kirbysetattr
アクセスよりも好ましい__dict__
直接。あなたはにつながる可能性があることの多くを心に留めておく必要があります__dict__
使用しているときに、そこにいない、または自分が望むことをしていない__dict__
しかし、setattr
実際に行うことと実質的に同じです。foo.bar = baz
。 - Mike Graham
その答えを使って考えるsettattr
あなたが本当に支援する必要があるなら、行く道はありますdict
。
しかし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()
辞書としてすべてのプロパティにアクセスする方法できない後で追加の属性を追加するのは、構築時に限られます。
property
。 - Mike Graham
属性名を辞書のキーとして使用しないのはなぜですか。
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ストレージクラスで使われているトリック)
例えば言う
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)
a.__dict__.update(x=100, y=300, z="blah")
- simno
辞書を使うのと同じように、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'
dict
変数の名ではありません、それはタイプを隠しますdict
- van