중첩 된 Python dict를 객체로 변환 하시겠습니까?
중첩 된 dicts 및 list가있는 dict의 속성 액세스를 사용하여 데이터를 얻는 우아한 방법을 찾고 있습니다 (예 : javascript 스타일 객체 구문).
예를 들면 다음과 같습니다.
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
이 방법으로 액세스 할 수 있어야합니다.
>>> x = dict2obj(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
bar
나는 이것이 재귀 없이는 불가능하다고 생각하지만 dicts에 대한 객체 스타일을 얻는 좋은 방법은 무엇입니까?
업데이트 : Python 2.6 이상에서 namedtuple
데이터 구조가 요구 사항에 적합한 지 고려 하십시오.
>>> from collections import namedtuple
>>> MyStruct = namedtuple('MyStruct', 'a b d')
>>> s = MyStruct(a=1, b={'c': 2}, d=['hi'])
>>> s
MyStruct(a=1, b={'c': 2}, d=['hi'])
>>> s.a
1
>>> s.b
{'c': 2}
>>> s.c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyStruct' object has no attribute 'c'
>>> s.d
['hi']
대안 (원래 답변 내용)은 다음과 같습니다.
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
그런 다음 다음을 사용할 수 있습니다.
>>> args = {'a': 1, 'b': 2}
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s.a
1
>>> s.b
2
class obj(object):
def __init__(self, d):
for a, b in d.items():
if isinstance(b, (list, tuple)):
setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b])
else:
setattr(self, a, obj(b) if isinstance(b, dict) else b)
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> x = obj(d)
>>> x.b.c
2
>>> x.d[1].foo
'bar'
놀랍게도 아무도 Bunch 를 언급하지 않았습니다 . 이 라이브러리는 독점적으로 dict 객체에 대한 속성 스타일 액세스를 제공하고 OP가 원하는 것을 정확하게 수행합니다. 데모 :
>>> from bunch import bunchify
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> x = bunchify(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
'bar'
Python 3 라이브러리는 https://github.com/Infinidat/munch에 있습니다. 크레딧은 codyzu 로 이동합니다
x = type('new_dict', (object,), d)
그런 다음 재귀를 추가하면 완료됩니다.
이것을 구현하는 방법을 편집 하십시오.
>>> d
{'a': 1, 'b': {'c': 2}, 'd': ['hi', {'foo': 'bar'}]}
>>> def obj_dic(d):
top = type('new', (object,), d)
seqs = tuple, list, set, frozenset
for i, j in d.items():
if isinstance(j, dict):
setattr(top, i, obj_dic(j))
elif isinstance(j, seqs):
setattr(top, i,
type(j)(obj_dic(sj) if isinstance(sj, dict) else sj for sj in j))
else:
setattr(top, i, j)
return top
>>> x = obj_dic(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
'bar'
이 namedtuple
작업을 수행 할 수 있는 컬렉션 도우미 가 있습니다.
from collections import namedtuple
d_named = namedtuple('Struct', d.keys())(*d.values())
In [7]: d_named
Out[7]: Struct(a=1, b={'c': 2}, d=['hi', {'foo': 'bar'}])
In [8]: d_named.a
Out[8]: 1
필자가 이전 예제의 가장 좋은 측면이라고 생각하는 것을 생각해 보았습니다.
class Struct:
'''The recursive class for building and representing objects with.'''
def __init__(self, obj):
for k, v in obj.iteritems():
if isinstance(v, dict):
setattr(self, k, Struct(v))
else:
setattr(self, k, v)
def __getitem__(self, val):
return self.__dict__[val]
def __repr__(self):
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for
(k, v) in self.__dict__.iteritems()))
class Struct(object):
"""Comment removed"""
def __init__(self, data):
for name, value in data.iteritems():
setattr(self, name, self._wrap(value))
def _wrap(self, value):
if isinstance(value, (tuple, list, set, frozenset)):
return type(value)([self._wrap(v) for v in value])
else:
return Struct(value) if isinstance(value, dict) else value
모든 깊이의 시퀀스 / dict / value 구조와 함께 사용할 수 있습니다.
dict이에서 오는 경우 json.loads()
한 줄로 dict 대신 dict 대신 객체로 설정할 수 있습니다.
import json
from collections import namedtuple
json.loads(data, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))
JSON 데이터를 Python 객체로 변환하는 방법 도 참조하십시오 .
dict 키를 객체 (또는 어려운 키에 대한 dict)로 액세스하려면 재귀 적으로 수행하고 원래 dict를 업데이트 할 수 있습니다.
class Dictate(object):
"""Object view of a dict, updating the passed in dict when values are set
or deleted. "Dictate" the contents of a dict...: """
def __init__(self, d):
# since __setattr__ is overridden, self.__dict = d doesn't work
object.__setattr__(self, '_Dictate__dict', d)
# Dictionary-like access / updates
def __getitem__(self, name):
value = self.__dict[name]
if isinstance(value, dict): # recursively view sub-dicts as objects
value = Dictate(value)
return value
def __setitem__(self, name, value):
self.__dict[name] = value
def __delitem__(self, name):
del self.__dict[name]
# Object-like access / updates
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
def __delattr__(self, name):
del self[name]
def __repr__(self):
return "%s(%r)" % (type(self).__name__, self.__dict)
def __str__(self):
return str(self.__dict)
사용법 예 :
d = {'a': 'b', 1: 2}
dd = Dictate(d)
assert dd.a == 'b' # Access like an object
assert dd[1] == 2 # Access like a dict
# Updates affect d
dd.c = 'd'
assert d['c'] == 'd'
del dd.a
del dd[1]
# Inner dicts are mapped
dd.e = {}
dd.e.f = 'g'
assert dd['e'].f == 'g'
assert d == {'c': 'd', 'e': {'f': 'g'}}
>>> def dict2obj(d):
if isinstance(d, list):
d = [dict2obj(x) for x in d]
if not isinstance(d, dict):
return d
class C(object):
pass
o = C()
for k in d:
o.__dict__[k] = dict2obj(d[k])
return o
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> x = dict2obj(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
'bar'
나는 AttrDict 와 Bunch를 모두 시도했다.도서관에서 사용하기에는 너무 느립니다. 친구와 함께 조사한 결과, 이러한 라이브러리를 작성하는 주된 방법은 라이브러리가 중첩 된 객체를 통해 적극적으로 재귀하고 사전 객체의 사본을 작성하는 것으로 나타났습니다. 이를 염두에두고 두 가지 주요 사항을 변경했습니다. 1) 속성을 게으르게로드했습니다. 2) 사전 오브젝트의 사본을 작성하는 대신 경량 프록시 오브젝트의 사본을 작성합니다. 이것이 최종 구현입니다. 이 코드를 사용하면 성능이 크게 향상됩니다. AttrDict 또는 Bunch를 사용할 때이 두 라이브러리는 각각 내 요청 시간의 1/2과 1/3을 소비했습니다 (what !?). 이 코드는 그 시간을 거의 아무것도 (0.5ms 범위) 줄였습니다. 이것은 물론 사용자의 요구에 따라 다르지만 코드에서이 기능을 사용하고 있다면
class DictProxy(object):
def __init__(self, obj):
self.obj = obj
def __getitem__(self, key):
return wrap(self.obj[key])
def __getattr__(self, key):
try:
return wrap(getattr(self.obj, key))
except AttributeError:
try:
return self[key]
except KeyError:
raise AttributeError(key)
# you probably also want to proxy important list properties along like
# items(), iteritems() and __len__
class ListProxy(object):
def __init__(self, obj):
self.obj = obj
def __getitem__(self, key):
return wrap(self.obj[key])
# you probably also want to proxy important list properties along like
# __iter__ and __len__
def wrap(value):
if isinstance(value, dict):
return DictProxy(value)
if isinstance(value, (tuple, list)):
return ListProxy(value)
return value
원래 구현을 참조하십시오 여기 로 https://stackoverflow.com/users/704327/michael-merickel을 .
주목해야 할 또 다른 사항은이 구현이 매우 단순하고 필요한 모든 메소드를 구현하지는 않는다는 것입니다. DictProxy 또는 ListProxy 객체에 필요한대로 작성해야합니다.
x.__dict__.update(d)
잘해야합니다.
시작해야합니다.
class dict2obj(object):
def __init__(self, d):
self.__dict__['d'] = d
def __getattr__(self, key):
value = self.__dict__['d'][key]
if type(value) == type({}):
return dict2obj(value)
return value
d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
x = dict2obj(d)
print x.a
print x.b.c
print x.d[1].foo
아직 목록에서는 작동하지 않습니다. __getitem__
dicts를 감싸려면 UserList에서 목록 을 감싸고 과부하 해야합니다.
나는 이미 여기에 많은 답변이 있고 파티에 늦었다는 것을 알고 있지만이 방법은 재귀 적으로 사전을 객체와 같은 구조로 변환합니다.
def dictToObject(d):
for k,v in d.items():
if isinstance(v, dict):
d[k] = dictToObject(v)
return namedtuple('object', d.keys())(*d.values())
# Dictionary created from JSON file
d = {
'primaryKey': 'id',
'metadata':
{
'rows': 0,
'lastID': 0
},
'columns':
{
'col2': {
'dataType': 'string',
'name': 'addressLine1'
},
'col1': {
'datatype': 'string',
'name': 'postcode'
},
'col3': {
'dataType': 'string',
'name': 'addressLine2'
},
'col0': {
'datatype': 'integer',
'name': 'id'
},
'col4': {
'dataType': 'string',
'name': 'contactNumber'
}
},
'secondaryKeys': {}
}
d1 = dictToObject(d)
d1.columns.col1 # == object(datatype='string', name='postcode')
d1.metadata.rows # == 0
얼마 전에 내가 거의 사용 했던 해결책을 설명하겠습니다 . 그러나 먼저, 내가하지 않은 이유는 다음 코드가 있다는 사실에 의해 설명됩니다.
d = {'from': 1}
x = dict2obj(d)
print x.from
이 오류가 발생합니다 :
File "test.py", line 20
print x.from == 1
^
SyntaxError: invalid syntax
"from"은 Python 키워드이므로 허용 할 수없는 특정 사전 키가 있습니다.
이제 내 솔루션은 이름을 직접 사용하여 사전 항목에 액세스 할 수 있습니다. 그러나 "사전 의미론"을 사용할 수도 있습니다. 사용법 예제가 포함 된 코드는 다음과 같습니다.
class dict2obj(dict):
def __init__(self, dict_):
super(dict2obj, self).__init__(dict_)
for key in self:
item = self[key]
if isinstance(item, list):
for idx, it in enumerate(item):
if isinstance(it, dict):
item[idx] = dict2obj(it)
elif isinstance(item, dict):
self[key] = dict2obj(item)
def __getattr__(self, key):
return self[key]
d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
x = dict2obj(d)
assert x.a == x['a'] == 1
assert x.b.c == x['b']['c'] == 2
assert x.d[1].foo == x['d'][1]['foo'] == "bar"
오래된 Q & A이지만 더 이야기 할 것이 있습니다. 재귀 dict에 대해 아무도 이야기하지 않는 것 같습니다. 이것은 내 코드입니다.
#!/usr/bin/env python
class Object( dict ):
def __init__( self, data = None ):
super( Object, self ).__init__()
if data:
self.__update( data, {} )
def __update( self, data, did ):
dataid = id(data)
did[ dataid ] = self
for k in data:
dkid = id(data[k])
if did.has_key(dkid):
self[k] = did[dkid]
elif isinstance( data[k], Object ):
self[k] = data[k]
elif isinstance( data[k], dict ):
obj = Object()
obj.__update( data[k], did )
self[k] = obj
obj = None
else:
self[k] = data[k]
def __getattr__( self, key ):
return self.get( key, None )
def __setattr__( self, key, value ):
if isinstance(value,dict):
self[key] = Object( value )
else:
self[key] = value
def update( self, *args ):
for obj in args:
for k in obj:
if isinstance(obj[k],dict):
self[k] = Object( obj[k] )
else:
self[k] = obj[k]
return self
def merge( self, *args ):
for obj in args:
for k in obj:
if self.has_key(k):
if isinstance(self[k],list) and isinstance(obj[k],list):
self[k] += obj[k]
elif isinstance(self[k],list):
self[k].append( obj[k] )
elif isinstance(obj[k],list):
self[k] = [self[k]] + obj[k]
elif isinstance(self[k],Object) and isinstance(obj[k],Object):
self[k].merge( obj[k] )
elif isinstance(self[k],Object) and isinstance(obj[k],dict):
self[k].merge( obj[k] )
else:
self[k] = [ self[k], obj[k] ]
else:
if isinstance(obj[k],dict):
self[k] = Object( obj[k] )
else:
self[k] = obj[k]
return self
def test01():
class UObject( Object ):
pass
obj = Object({1:2})
d = {}
d.update({
"a": 1,
"b": {
"c": 2,
"d": [ 3, 4, 5 ],
"e": [ [6,7], (8,9) ],
"self": d,
},
1: 10,
"1": 11,
"obj": obj,
})
x = UObject(d)
assert x.a == x["a"] == 1
assert x.b.c == x["b"]["c"] == 2
assert x.b.d[0] == 3
assert x.b.d[1] == 4
assert x.b.e[0][0] == 6
assert x.b.e[1][0] == 8
assert x[1] == 10
assert x["1"] == 11
assert x[1] != x["1"]
assert id(x) == id(x.b.self.b.self) == id(x.b.self)
assert x.b.self.a == x.b.self.b.self.a == 1
x.x = 12
assert x.x == x["x"] == 12
x.y = {"a":13,"b":[14,15]}
assert x.y.a == 13
assert x.y.b[0] == 14
def test02():
x = Object({
"a": {
"b": 1,
"c": [ 2, 3 ]
},
1: 6,
2: [ 8, 9 ],
3: 11,
})
y = Object({
"a": {
"b": 4,
"c": [ 5 ]
},
1: 7,
2: 10,
3: [ 12 , 13 ],
})
z = {
3: 14,
2: 15,
"a": {
"b": 16,
"c": 17,
}
}
x.merge( y, z )
assert 2 in x.a.c
assert 3 in x.a.c
assert 5 in x.a.c
assert 1 in x.a.b
assert 4 in x.a.b
assert 8 in x[2]
assert 9 in x[2]
assert 10 in x[2]
assert 11 in x[3]
assert 12 in x[3]
assert 13 in x[3]
assert 14 in x[3]
assert 15 in x[2]
assert 16 in x.a.b
assert 17 in x.a.c
if __name__ == '__main__':
test01()
test02()
이 작은 패러다임의 내 버전을 업로드하고 싶었습니다.
class Struct(dict):
def __init__(self,data):
for key, value in data.items():
if isinstance(value, dict):
setattr(self, key, Struct(value))
else:
setattr(self, key, type(value).__init__(value))
dict.__init__(self,data)
클래스로 가져온 유형의 속성을 유지합니다. 내 유일한 관심사는 구문 분석 사전에서 메서드를 덮어 쓰는 것입니다. 그러나 그렇지 않으면 견실 한 것 같습니다!
from mock import Mock
d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
my_data = Mock(**d)
# We got
# my_data.a == 1
사용자 정의 객체 후크를 사용하여 표준 라이브러리 의 json
모듈 을 활용할 수 있습니다 .
import json
class obj(object):
def __init__(self, dict_):
self.__dict__.update(dict_)
def dict2obj(d):
return json.loads(json.dumps(d), object_hook=obj)
사용법 예 :
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ['hi', {'foo': 'bar'}]}
>>> o = dict2obj(d)
>>> o.a
1
>>> o.b.c
2
>>> o.d[0]
u'hi'
>>> o.d[1].foo
u'bar'
그리고와 같이 엄격하게 읽기 전용 이 아닙니다namedtuple
. 즉 구조가 아닌 값을 변경할 수 있습니다.
>>> o.b.c = 3
>>> o.b.c
3
이것도 잘 작동합니다
class DObj(object):
pass
dobj = Dobj()
dobj.__dict__ = {'a': 'aaa', 'b': 'bbb'}
print dobj.a
>>> aaa
print dobj.b
>>> bbb
나는 dicts 목록을 객체 목록으로 재귀 적으로 변환 해야하는 경우를 우연히 발견 했으므로 여기에서 Roberto의 발췌 부분을 기반으로 작업이 어떻게 이루어 졌습니까?
def dict2obj(d):
if isinstance(d, dict):
n = {}
for item in d:
if isinstance(d[item], dict):
n[item] = dict2obj(d[item])
elif isinstance(d[item], (list, tuple)):
n[item] = [dict2obj(elem) for elem in d[item]]
else:
n[item] = d[item]
return type('obj_from_dict', (object,), n)
elif isinstance(d, (list, tuple,)):
l = []
for item in d:
l.append(dict2obj(item))
return l
else:
return d
명백한 이유로 모든 튜플은 동등한 목록으로 변환됩니다.
이것이 귀하의 모든 답변이 저에게 도움이 된 것처럼 누군가에게 도움이되기를 바랍니다.
당신 dict
을 __dict__
빈 객체에 할당하는 것은 어떻습니까?
class Object:
"""If your dict is "flat", this is a simple way to create an object from a dict
>>> obj = Object()
>>> obj.__dict__ = d
>>> d.a
1
"""
pass
물론 dict을 재귀 적으로 걸지 않으면 중첩 된 dict 예제에서 실패합니다.
# For a nested dict, you need to recursively update __dict__
def dict2obj(d):
"""Convert a dict to an object
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> obj = dict2obj(d)
>>> obj.b.c
2
>>> obj.d
["hi", {'foo': "bar"}]
"""
try:
d = dict(d)
except (TypeError, ValueError):
return d
obj = Object()
for k, v in d.iteritems():
obj.__dict__[k] = dict2obj(v)
return obj
그리고 예제 목록 요소는 아마도 Mapping
다음과 같이 (키, 값) 쌍의 목록이 될 것입니다.
>>> d = {'a': 1, 'b': {'c': 2}, 'd': [("hi", {'foo': "bar"})]}
>>> obj = dict2obj(d)
>>> obj.d.hi.foo
"bar"
SilentGhost의 원래 제안을 구현하는 또 다른 방법은 다음과 같습니다.
def dict2obj(d):
if isinstance(d, dict):
n = {}
for item in d:
if isinstance(d[item], dict):
n[item] = dict2obj(d[item])
elif isinstance(d[item], (list, tuple)):
n[item] = [dict2obj(elem) for elem in d[item]]
else:
n[item] = d[item]
return type('obj_from_dict', (object,), n)
else:
return d
또 다른 구현은 다음과 같습니다.
class DictObj(object):
def __init__(self, d):
self.__dict__ = d
def dict_to_obj(d):
if isinstance(d, (list, tuple)): return map(dict_to_obj, d)
elif not isinstance(d, dict): return d
return DictObj(dict((k, dict_to_obj(v)) for (k,v) in d.iteritems()))
[편집] 다른 딕트 만이 아니라리스트 내의 딕트도 처리하는 것에 관해 놓쳤습니다. 수정 사항이 추가되었습니다.
class Struct(dict):
def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
self[name] = value
def copy(self):
return Struct(dict.copy(self))
용법:
points = Struct(x=1, y=2)
# Changing
points['x'] = 2
points.y = 1
# Accessing
points['x'], points.x, points.get('x') # 2 2 2
points['y'], points.y, points.get('y') # 1 1 1
# Accessing inexistent keys/attrs
points['z'] # KeyError: z
points.z # AttributeError: z
# Copying
points_copy = points.copy()
points.x = 2
points_copy.x # 1
이건 어때:
from functools import partial
d2o=partial(type, "d2o", ())
다음과 같이 사용할 수 있습니다 :
>>> o=d2o({"a" : 5, "b" : 3})
>>> print o.a
5
>>> print o.b
3
dict는 숫자, 문자열 및 dict로 구성되어 있다고 생각합니다. 따라서 튜플, 목록 및 기타 유형이 dict의 최종 차원에 나타나지 않는 상황을 무시합니다.
상속과 재귀를 결합하여 인쇄 문제를 편리하게 해결하고 데이터를 쿼리하는 두 가지 방법, 즉 데이터를 편집하는 방법을 제공합니다.
학생에 대한 정보를 설명하는 아래 예를 참조하십시오.
group=["class1","class2","class3","class4",]
rank=["rank1","rank2","rank3","rank4","rank5",]
data=["name","sex","height","weight","score"]
#build a dict based on the lists above
student_dic=dict([(g,dict([(r,dict([(d,'') for d in data])) for r in rank ]))for g in group])
#this is the solution
class dic2class(dict):
def __init__(self, dic):
for key,val in dic.items():
self.__dict__[key]=self[key]=dic2class(val) if isinstance(val,dict) else val
student_class=dic2class(student_dic)
#one way to edit:
student_class.class1.rank1['sex']='male'
student_class.class1.rank1['name']='Nan Xiang'
#two ways to query:
print student_class.class1.rank1
print student_class.class1['rank1']
print '-'*50
for rank in student_class.class1:
print getattr(student_class.class1,rank)
결과 :
{'score': '', 'sex': 'male', 'name': 'Nan Xiang', 'weight': '', 'height': ''}
{'score': '', 'sex': 'male', 'name': 'Nan Xiang', 'weight': '', 'height': ''}
--------------------------------------------------
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
{'score': '', 'sex': 'male', 'name': 'Nan Xiang', 'weight': '', 'height': ''}
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
내 대답을 구축 " 파이썬 : 동적으로 클래스에 속성을 추가하는 방법? "
class data(object):
def __init__(self,*args,**argd):
self.__dict__.update(dict(*args,**argd))
def makedata(d):
d2 = {}
for n in d:
d2[n] = trydata(d[n])
return data(d2)
def trydata(o):
if isinstance(o,dict):
return makedata(o)
elif isinstance(o,list):
return [trydata(i) for i in o]
else:
return o
당신은 전화를 makedata
당신이 변환, 아니면 원하는 사전을 trydata
당신이 입력으로 기대에 따라, 그리고 데이터 오브젝트를 뱉어.
노트:
trydata
더 많은 기능이 필요한 경우 elifs를 추가 할 수 있습니다 .- 당신이 원
x.a = {}
하거나 비슷한 경우 분명히 작동하지 않습니다 . - 읽기 전용 버전을 원하면 원래 답변 의 클래스 데이터를 사용하십시오 .
다음은 명명 된 튜플이있는 중첩 가능 버전입니다.
from collections import namedtuple
class Struct(object):
def __new__(cls, data):
if isinstance(data, dict):
return namedtuple(
'Struct', data.iterkeys()
)(
*(Struct(val) for val in data.values())
)
elif isinstance(data, (tuple, list, set, frozenset)):
return type(data)(Struct(_) for _ in data)
else:
return data
=>
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> s = Struct(d)
>>> s.d
['hi', Struct(foo='bar')]
>>> s.d[0]
'hi'
>>> s.d[1].foo
'bar'
__getattr__
호출되지 않는 데 문제가 있었 으므로 새로운 스타일 클래스 버전을 작성했습니다.
class Struct(object):
'''The recursive class for building and representing objects with.'''
class NoneStruct(object):
def __getattribute__(*args):
return Struct.NoneStruct()
def __eq__(self, obj):
return obj == None
def __init__(self, obj):
for k, v in obj.iteritems():
if isinstance(v, dict):
setattr(self, k, Struct(v))
else:
setattr(self, k, v)
def __getattribute__(*args):
try:
return object.__getattribute__(*args)
except:
return Struct.NoneStruct()
def __repr__(self):
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for
(k, v) in self.__dict__.iteritems()))
이 버전 NoneStruct
에는 속성이 호출되어 설정되지 않은 속성이 추가 될 때 추가 됩니다. 이를 통해 None 테스트를 통해 속성이 있는지 확인할 수 있습니다. 정확한 dict 입력을 알 수 없을 때 매우 유용합니다 (설정 등).
bla = Struct({'a':{'b':1}})
print(bla.a.b)
>> 1
print(bla.a.c == None)
>> True
참고 URL : https://stackoverflow.com/questions/1305532/convert-nested-python-dict-to-object
'development' 카테고리의 다른 글
대소 문자를 구분하지 않는 문자열 비교는 어떻게합니까? (0) | 2020.02.12 |
---|---|
파일 연결 해제에 실패했습니다. (0) | 2020.02.12 |
Objective-C에서 추상 클래스 작성 (0) | 2020.02.12 |
스플래시 화면을 만들려면 어떻게합니까? (0) | 2020.02.12 |
이미지 나 범위 태그를 사용하지 않고 CSS를 통해 UL / LI HTML 목록에서 글 머리 기호 색상을 설정하는 방법 (0) | 2020.02.12 |