사전의 구성원에 액세스하기 위해 점 ". "을(를) 사용하는 방법
Python 사전 구성원에 점 "?"을 통해 접근할 수 있도록 하려면 어떻게 해야 합니다.
를 들어, '는 것이 '는 것이 좋다'라고 씁니다.mydict['val']
쓰고 mydict.val
.
또, 네스트 된 딕트에도 액세스 하고 싶습니다.예를들면
mydict.mydict2.val
참조할 수 있다
mydict = { 'mydict2': { 'val': ... } }
항상 이걸 util 파일로 보관해뒀어요당신의 수업에서도 믹스로 사용할 수 있습니다.
class dotdict(dict):
"""dot.notation access to dictionary attributes"""
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
mydict = {'val':'it works'}
nested_dict = {'val':'nested works too'}
mydict = dotdict(mydict)
mydict.val
# 'it works'
mydict.nested = dotdict(nested_dict)
mydict.nested.val
# 'nested works too'
내가방 、 업업업업업할 。에서는, 「」를 할 수 .Map
다른 사전(json 직렬화 포함)과 같은 객체 또는 점 표기법.도움이 되었으면 합니다.
class Map(dict):
"""
Example:
m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
"""
def __init__(self, *args, **kwargs):
super(Map, self).__init__(*args, **kwargs)
for arg in args:
if isinstance(arg, dict):
for k, v in arg.iteritems():
self[k] = v
if kwargs:
for k, v in kwargs.iteritems():
self[k] = v
def __getattr__(self, attr):
return self.get(attr)
def __setattr__(self, key, value):
self.__setitem__(key, value)
def __setitem__(self, key, value):
super(Map, self).__setitem__(key, value)
self.__dict__.update({key: value})
def __delattr__(self, item):
self.__delitem__(item)
def __delitem__(self, key):
super(Map, self).__delitem__(key)
del self.__dict__[key]
사용 예:
m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
# Or
m['new_key'] = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']
dotmap
★★★★★★★★★★★★★★★★★를 통해pip
pip install dotmap
은 당신이 을 하고 분류를 합니다.dict
from dotmap import DotMap
m = DotMap()
m.hello = 'world'
m.hello
m.hello += '!'
# m.hello and m['hello'] now both return 'world!'
m.val = 5
m.val2 = 'Sam'
,, 이, 이, 이, 이, 이, 이, 이, 능, on, on, on, on, on, on, on, on, on, on, on, on로 변환할 수 .dict
★★★★★★★★★★★★★★★★★★:
d = m.toDict()
m = DotMap(d) # automatic conversion in constructor
은, 「」에 , 「」라고 하는 입니다.dict
해서 형상으로 수 요.DotMap
쉽게 접근할 수 있습니다.
import json
jsonDict = json.loads(text)
data = DotMap(jsonDict)
print data.location.city
됩니다.DotMap
을 사용하다
m = DotMap()
m.people.steve.age = 31
번치와의 비교
완전 공개:저는 닷맵을 만든 사람입니다.제가 만든 이유는Bunch
되어 있었습니다.
- 순서 항목이 추가되고 해당 순서로 반복된다는 것을 기억하십시오.
- 아이
DotMap
creation을때 더 됩니다. - 성 a로
dict
를 재귀적으로 합니다.dict
인스턴스 에대한에 인스턴스DotMap
이러할 것이라 맹세에서 dict구현에서 파생됩니다 및을 구현합니다.__getattr__
그리고 그리고.__setattr__
..
아니면 아주 비슷한 번치를 사용하셔도 됩니다.
빌트인 딕트 수업을 멍키패치하는 건 불가능할 것 같아.
사용 사용하다SimpleNamespace
::
>>> from types import SimpleNamespace
>>> d = dict(x=[1, 2], y=['a', 'b'])
>>> ns = SimpleNamespace(**d)
>>> ns.x
[1, 2]
>>> ns
namespace(x=[1, 2], y=['a', 'b'])
패브릭의 실장은 매우 훌륭하고 최소한으로 억제되어 있습니다.네스트된 접근을 허용하도록 확장하면defaultdict
하게 되었고, 결과: 이렇게 생겼습니다.결과는 다음과 같습니다.
from collections import defaultdict
class AttributeDict(defaultdict):
def __init__(self):
super(AttributeDict, self).__init__(AttributeDict)
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(key)
def __setattr__(self, key, value):
self[key] = value
다음과 같이 사용합니다.
keys = AttributeDict()
keys.abc.xyz.x = 123
keys.abc.xyz.a.b.c = 234
이는 쿠겔이 "Derive from dict and explement and"라고 대답한 내용을 조금 더 자세히 설명한 것이다.이제 방법을 알겠군!
이거 해봤어요.
class dotdict(dict):
def __getattr__(self, name):
return self[name]
당신해볼 수 만들어 볼 수 있는 있습니다__getattribute__
too.너무.
만약 당신이 다층 것이라 맹세에서, 모든 dit를dotdict유형으로 만들면 충분합니다 도굴 init고 싶dotdict의 모든 것이라 맹세 형식, 좋을 것이다.여러레이어 dit에서 초기화하려면 보십시오구현해 이것을.__init__
too.너무.
나는 최근에 같은 일을 하는 '박스' 도서관을 우연히 발견했다.
설치 명령:설치 명령:pip install python-box
예제:
from box import Box
mydict = {"key1":{"v1":0.375,
"v2":0.625},
"key2":0.125,
}
mydict = Box(mydict)
print(mydict.key1.v1)
큰 네스트된 딕트가 있을 때 파이썬 재귀 오류를 발생시키는 닷맵과 같은 기존 라이브러리보다 더 효과적이라는 것을 알게 되었습니다.
라이브러리 및 상세 링크:https://pypi.org/project/python-box/
수정된 사전을 피클하려면 위의 답변에 몇 가지 상태 방법을 추가해야 합니다.
class DotDict(dict):
"""dot.notation access to dictionary attributes"""
def __getattr__(self, attr):
return self.get(attr)
__setattr__= dict.__setitem__
__delattr__= dict.__delitem__
def __getstate__(self):
return self
def __setstate__(self, state):
self.update(state)
self.__dict__ = self
하지 마세요. 속성 액세스와 인덱싱은 Python에서는 별개입니다.이것들이 같은 처리를 하는 것을 원하지 않습니다.클래스를 만듭니다(아마도 에 의해 만들어진 클래스).namedtuple
하여 Atribute를 사용해야 []
에서 입니다.
이것은 Simple Namespace를 사용하여 실행할 수 있습니다.
from types import SimpleNamespace
# Assign values
args = SimpleNamespace()
args.username = 'admin'
# Retrive values
print(args.username) # output: admin
쿠겔의 대답을 바탕으로 마이크 그레이엄의 경고문을 참고해서 포장지를 만들면 어떨까?
class DictWrap(object):
""" Wrap an existing dict, or create a new one, and access with either dot
notation or key lookup.
The attribute _data is reserved and stores the underlying dictionary.
When using the += operator with create=True, the empty nested dict is
replaced with the operand, effectively creating a default dictionary
of mixed types.
args:
d({}): Existing dict to wrap, an empty dict is created by default
create(True): Create an empty, nested dict instead of raising a KeyError
example:
>>>dw = DictWrap({'pp':3})
>>>dw.a.b += 2
>>>dw.a.b += 2
>>>dw.a['c'] += 'Hello'
>>>dw.a['c'] += ' World'
>>>dw.a.d
>>>print dw._data
{'a': {'c': 'Hello World', 'b': 4, 'd': {}}, 'pp': 3}
"""
def __init__(self, d=None, create=True):
if d is None:
d = {}
supr = super(DictWrap, self)
supr.__setattr__('_data', d)
supr.__setattr__('__create', create)
def __getattr__(self, name):
try:
value = self._data[name]
except KeyError:
if not super(DictWrap, self).__getattribute__('__create'):
raise
value = {}
self._data[name] = value
if hasattr(value, 'items'):
create = super(DictWrap, self).__getattribute__('__create')
return DictWrap(value, create)
return value
def __setattr__(self, name, value):
self._data[name] = value
def __getitem__(self, key):
try:
value = self._data[key]
except KeyError:
if not super(DictWrap, self).__getattribute__('__create'):
raise
value = {}
self._data[key] = value
if hasattr(value, 'items'):
create = super(DictWrap, self).__getattribute__('__create')
return DictWrap(value, create)
return value
def __setitem__(self, key, value):
self._data[key] = value
def __iadd__(self, other):
if self._data:
raise TypeError("A Nested dict will only be replaced if it's empty")
else:
return other
epool의 답변을 기반으로 하기 위해 이 버전에서는 닷 연산자를 통해 안에 있는 모든 dict에 액세스할 수 있습니다.
foo = {
"bar" : {
"baz" : [ {"boo" : "hoo"} , {"baba" : "loo"} ]
}
}
를 들면, 「 」입니다.foo.bar.baz[1].baba
"loo"
.
class Map(dict):
def __init__(self, *args, **kwargs):
super(Map, self).__init__(*args, **kwargs)
for arg in args:
if isinstance(arg, dict):
for k, v in arg.items():
if isinstance(v, dict):
v = Map(v)
if isinstance(v, list):
self.__convert(v)
self[k] = v
if kwargs:
for k, v in kwargs.items():
if isinstance(v, dict):
v = Map(v)
elif isinstance(v, list):
self.__convert(v)
self[k] = v
def __convert(self, v):
for elem in range(0, len(v)):
if isinstance(v[elem], dict):
v[elem] = Map(v[elem])
elif isinstance(v[elem], list):
self.__convert(v[elem])
def __getattr__(self, attr):
return self.get(attr)
def __setattr__(self, key, value):
self.__setitem__(key, value)
def __setitem__(self, key, value):
super(Map, self).__setitem__(key, value)
self.__dict__.update({key: value})
def __delattr__(self, item):
self.__delitem__(item)
def __delitem__(self, key):
super(Map, self).__delitem__(key)
del self.__dict__[key]
__getattr__
심플한 3..3에서
class myDict(dict):
def __getattr__(self,val):
return self[val]
blockBody=myDict()
blockBody['item1']=10000
blockBody['item2']="StackOverflow"
print(blockBody.item1)
print(blockBody.item2)
출력:
10000
StackOverflow
나는 뭉크를 좋아하고 닷 액세스 외에 편리한 옵션도 많이 제공한다.
수입 뭉크
temp_1 = {'person': {fname': 'senthil', 'lname': 'ramalingam'}
dict_munch=munch.munchify(munch_1)
dict_dict.person.fname
언어 자체는 이를 지원하지 않지만, 때때로 이것은 여전히 유용한 요구 사항입니다.Bunch 레시피 외에 점 문자열로 사전에 접속할 수 있는 간단한 메서드도 작성할 수 있습니다.
def get_var(input_dict, accessor_string):
"""Gets data from a dictionary using a dotted accessor-string"""
current_data = input_dict
for chunk in accessor_string.split('.'):
current_data = current_data.get(chunk, {})
return current_data
다음과 같은 것을 지원할 수 있습니다.
>> test_dict = {'thing': {'spam': 12, 'foo': {'cheeze': 'bar'}}}
>> output = get_var(test_dict, 'thing.spam.foo.cheeze')
>> print output
'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 오브젝트에 기입해야 합니다.
def dict_to_object(dick):
# http://stackoverflow.com/a/1305663/968442
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
return Struct(**dick)
dict
이의를 제기할 수 있습니다.액세스하기 직전에 일회용 개체를 만들 수 있습니다.
d = dict_to_object(d)
이 솔루션은 epool에서 제공하는 솔루션을 개량한 것으로, OP가 네스트된 dict에 일관되게 액세스 할 수 있도록 합니다.epool별 솔루션에서는 중첩된 딕트에 액세스할 수 없습니다.
class YAMLobj(dict):
def __init__(self, args):
super(YAMLobj, self).__init__(args)
if isinstance(args, dict):
for k, v in args.iteritems():
if not isinstance(v, dict):
self[k] = v
else:
self.__setattr__(k, YAMLobj(v))
def __getattr__(self, attr):
return self.get(attr)
def __setattr__(self, key, value):
self.__setitem__(key, value)
def __setitem__(self, key, value):
super(YAMLobj, self).__setitem__(key, value)
self.__dict__.update({key: value})
def __delattr__(self, item):
self.__delitem__(item)
def __delitem__(self, key):
super(YAMLobj, self).__delitem__(key)
del self.__dict__[key]
할 수 A.B.C.D
dict, 목록, dict 목록 및 dict 목록의 무한 중첩 수준.
피클링도 지원
class DotDict(dict):
# https://stackoverflow.com/a/70665030/913098
"""
Example:
m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
Iterable are assumed to have a constructor taking list as input.
"""
def __init__(self, *args, **kwargs):
super(DotDict, self).__init__(*args, **kwargs)
args_with_kwargs = []
for arg in args:
args_with_kwargs.append(arg)
args_with_kwargs.append(kwargs)
args = args_with_kwargs
for arg in args:
if isinstance(arg, dict):
for k, v in arg.items():
self[k] = v
if isinstance(v, dict):
self[k] = DotDict(v)
elif isinstance(v, str) or isinstance(v, bytes):
self[k] = v
elif isinstance(v, Iterable):
klass = type(v)
map_value: List[Any] = []
for e in v:
map_e = DotDict(e) if isinstance(e, dict) else e
map_value.append(map_e)
self[k] = klass(map_value)
def __getattr__(self, attr):
return self.get(attr)
def __setattr__(self, key, value):
self.__setitem__(key, value)
def __setitem__(self, key, value):
super(DotDict, self).__setitem__(key, value)
self.__dict__.update({key: value})
def __delattr__(self, item):
self.__delitem__(item)
def __delitem__(self, key):
super(DotDict, self).__delitem__(key)
del self.__dict__[key]
def __getstate__(self):
return self.__dict__
def __setstate__(self, d):
self.__dict__.update(d)
if __name__ == "__main__":
import pickle
def test_map():
d = {
"a": 1,
"b": {
"c": "d",
"e": 2,
"f": None
},
"g": [],
"h": [1, "i"],
"j": [1, "k", {}],
"l":
[
1,
"m",
{
"n": [3],
"o": "p",
"q": {
"r": "s",
"t": ["u", 5, {"v": "w"}, ],
"x": ("z", 1)
}
}
],
}
map_d = DotDict(d)
w = map_d.l[2].q.t[2].v
assert w == "w"
pickled = pickle.dumps(map_d)
unpickled = pickle.loads(pickled)
assert unpickled == map_d
kwargs_check = DotDict(a=1, b=[dict(c=2, d="3"), 5])
assert kwargs_check.b[0].d == "3"
kwargs_and_args_check = DotDict(d, a=1, b=[dict(c=2, d="3"), 5])
assert kwargs_and_args_check.l[2].q.t[2].v == "w"
assert kwargs_and_args_check.b[0].d == "3"
test_map()
이 방법은 중첩된 딕트에서도 작동하며 나중에 추가된 딕트도 동일하게 동작합니다.
class DotDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Recursively turn nested dicts into DotDicts
for key, value in self.items():
if type(value) is dict:
self[key] = DotDict(value)
def __setitem__(self, key, item):
if type(item) is dict:
item = DotDict(item)
super().__setitem__(key, item)
__setattr__ = __setitem__
__getattr__ = dict.__getitem__
「」를 사용합니다.namedtuple
도트 액세스를 허용합니다.
그것은 태플의 성질을 가지고 있는 가벼운 물건과 같다.
도트 연산자를 사용하여 속성을 정의하고 액세스할 수 있습니다.
from collections import namedtuple
Data = namedtuple('Data', ['key1', 'key2'])
dataObj = Data(val1, key2=val2) # can instantiate using keyword arguments and positional arguments
도트 연산자를 사용하여 액세스
dataObj.key1 # Gives val1
datObj.key2 # Gives val2
태플 인덱스를 사용한 액세스
dataObj[0] # Gives val1
dataObj[1] # Gives val2
하지만 이것은 명령어가 아니라 태플이라는 것을 기억해라.그래서 아래 코드는 오류를 줄 것이다.
dataObj['key1'] # Gives TypeError: tuple indices must be integers or slices, not str
참조: named tuple
오래된 질문이지만 최근에 알게 된 것은sklearn
에는, 「」이 .dict
로 할 수 즉 「」, 「」Bunch
https://scikit-learn.org/stable/modules/generated/sklearn.utils.Bunch.html#sklearn.utils.Bunchhttps.org/stable/modules/generated/sklearn.utils.Bunch.html#sklearn.utils.Bunch
가장 심플한 솔루션
pass 문만 포함하는 클래스를 정의합니다.이 클래스에 대한 개체를 만들고 점 표기법을 사용합니다.
class my_dict:
pass
person = my_dict()
person.id = 1 # create using dot notation
person.phone = 9999
del person.phone # Remove a property using dot notation
name_data = my_dict()
name_data.first_name = 'Arnold'
name_data.last_name = 'Schwarzenegger'
person.name = name_data
person.name.first_name # dot notation access for nested properties - gives Arnold
도트 액세스(어레이 액세스가 아님)를 얻는 간단한 방법 중 하나는 Python에서 플레인 오브젝트를 사용하는 것입니다.다음과 같이 합니다.
class YourObject:
def __init__(self, *args, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
...그리고 다음과 같이 사용합니다.
>>> obj = YourObject(key="value")
>>> print(obj.key)
"value"
...dict로 변환하려면:
>>> print(obj.__dict__)
{"key": "value"}
@derek73의 답변은 매우 깔끔하지만 절이거나 복사할 수 없으며, 다시 돌아온다.None
을 사용하다이 문제는 다음 코드로 해결됩니다.
편집: 위의 답변에서 동일한 포인트(업보드)를 다루는 답변을 찾을 수 없습니다.참고로 여기에 답을 남깁니다.
class dotdict(dict):
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
점선 경로 문자열을 사용하여 사전에 액세스해야 했기 때문에 다음과 같은 방법을 생각해 냈습니다.
def get_value_from_path(dictionary, parts):
""" extracts a value from a dictionary using a dotted path string """
if type(parts) is str:
parts = parts.split('.')
if len(parts) > 1:
return get_value_from_path(dictionary[parts[0]], parts[1:])
return dictionary[parts[0]]
a = {'a':{'b':'c'}}
print(get_value_from_path(a, 'a.b')) # c
저는 10년 이상 된 화재에 또 다른 통나무를 추가하는 것은 싫지만, 제가 최근에 내놓은 도서관도 살펴보고 싶습니다. 사실 올해에요.
비교적 작은 라이브러리이기 때문에 벤치마크의 취득(액세스) 및 설정(작성) 시간도 적어도 다른 대체 라이브러리보다 매우 우수합니다.
dotwiz
★★★★★★★★★★★★★★★★★를 통해pip
pip install dotwiz
은 당신이 을 하고 분류를 합니다.dict
from dotwiz import DotWiz
dw = DotWiz()
dw.hello = 'world'
dw.hello
dw.hello += '!'
# dw.hello and dw['hello'] now both return 'world!'
dw.val = 5
dw.val2 = 'Sam'
,, 이, 이, 이, 이, 이, 이, 이, 능, on, on, on, on, on, on, on, on, on, on, on, on로 변환할 수 .dict
★★★★★★★★★★★★★★★★★★:
d = dw.to_dict()
dw = DotWiz(d) # automatic conversion in constructor
은, 「」에 , 「」라고 하는 입니다.dict
해서 형상으로 수 요.DotWiz
쉽게 접근할 수 있습니다.
import json
json_dict = json.loads(text)
data = DotWiz(json_dict)
print data.location.city
마지막으로, 현재 작업 중인 흥미로운 것은 기존 기능 요청으로, 새로운 자식이 자동으로 생성됩니다.DotWiz
인스턴스는 네가:이런 짓을 할 수 있다.다음과 같은 작업을 수행할 수 있습니다.
dw = DotWiz()
dw['people.steve.age'] = 31
dw
# ✫(people=✫(steve=✫(age=31)))
비교 비교와dotmap
아래와 같은 빠른 성능 비교를 추가했습니다.
첫째,먼저 두 라이브러리를모두 설치합니다와 도서관을 설치한다.pip
::
pip install dotwiz dotmap
벤치마크를 위해 다음 코드를 생각해 냈습니다.
from timeit import timeit
from dotwiz import DotWiz
from dotmap import DotMap
d = {'hey': {'so': [{'this': {'is': {'pretty': {'cool': True}}}}]}}
dw = DotWiz(d)
# ✫(hey=✫(so=[✫(this=✫(is=✫(pretty={'cool'})))]))
dm = DotMap(d)
# DotMap(hey=DotMap(so=[DotMap(this=DotMap(is=DotMap(pretty={'cool'})))]))
assert dw.hey.so[0].this['is'].pretty.cool == dm.hey.so[0].this['is'].pretty.cool
n = 100_000
print('dotwiz (create): ', round(timeit('DotWiz(d)', number=n, globals=globals()), 3))
print('dotmap (create): ', round(timeit('DotMap(d)', number=n, globals=globals()), 3))
print('dotwiz (get): ', round(timeit("dw.hey.so[0].this['is'].pretty.cool", number=n, globals=globals()), 3))
print('dotmap (get): ', round(timeit("dm.hey.so[0].this['is'].pretty.cool", number=n, globals=globals()), 3))
M1 Mac에서 Python 3.10을 실행한 결과:
dotwiz (create): 0.189
dotmap (create): 1.085
dotwiz (get): 0.014
dotmap (get): 0.335
아니라 관측소의 질문에 직접적으로 대답이 아니라 물 속에 그리고 아마도 some.에게 유용한 것입니다.OP의 질문에 대한 직접적인 답변은 아니지만,일부에서 영감을 얻었으며,아마도유용한 질문일 것입니다.나는 객체 기반 해결책솔루션을 만들었습니다 기반 객체 내부 내부시스템을 사용하여를 사용하여 만들었습니다.__dict__
(방법이 없어 최적화된 코드에서는)(최적화된 코드는 아닙니다).
payload = {
"name": "John",
"location": {
"lat": 53.12312312,
"long": 43.21345112
},
"numbers": [
{
"role": "home",
"number": "070-12345678"
},
{
"role": "office",
"number": "070-12345679"
}
]
}
class Map(object):
"""
Dot style access to object members, access raw values
with an underscore e.g.
class Foo(Map):
def foo(self):
return self.get('foo') + 'bar'
obj = Foo(**{'foo': 'foo'})
obj.foo => 'foobar'
obj._foo => 'foo'
"""
def __init__(self, *args, **kwargs):
for arg in args:
if isinstance(arg, dict):
for k, v in arg.iteritems():
self.__dict__[k] = v
self.__dict__['_' + k] = v
if kwargs:
for k, v in kwargs.iteritems():
self.__dict__[k] = v
self.__dict__['_' + k] = v
def __getattribute__(self, attr):
if hasattr(self, 'get_' + attr):
return object.__getattribute__(self, 'get_' + attr)()
else:
return object.__getattribute__(self, attr)
def get(self, key):
try:
return self.__dict__.get('get_' + key)()
except (AttributeError, TypeError):
return self.__dict__.get(key)
def __repr__(self):
return u"<{name} object>".format(
name=self.__class__.__name__
)
class Number(Map):
def get_role(self):
return self.get('role')
def get_number(self):
return self.get('number')
class Location(Map):
def get_latitude(self):
return self.get('lat') + 1
def get_longitude(self):
return self.get('long') + 1
class Item(Map):
def get_name(self):
return self.get('name') + " Doe"
def get_location(self):
return Location(**self.get('location'))
def get_numbers(self):
return [Number(**n) for n in self.get('numbers')]
# Tests
obj = Item({'foo': 'bar'}, **payload)
assert type(obj) == Item
assert obj._name == "John"
assert obj.name == "John Doe"
assert type(obj.location) == Location
assert obj.location._lat == 53.12312312
assert obj.location._long == 43.21345112
assert obj.location.latitude == 54.12312312
assert obj.location.longitude == 44.21345112
for n in obj.numbers:
assert type(n) == Number
if n.role == 'home':
assert n.number == "070-12345678"
if n.role == 'office':
assert n.number == "070-12345679"
@derek73의 답변은 다음과 같습니다.사용하고 있다dict.__getitem__
~하듯이로__getattr__
그래서 그것은 여전히그래서 그것은 여전히 던진다를 throw 합니다.KeyError
dict public 메서드의 이름을 " 접두사"로 변경합니다("를 붙이면 다음과 같은 특수한 메서드의 이름 경합이 발생합니다).__get__
어떤 것이 설명자 메서드로 계산 처리될 것이다.기술자방법으로 취급됩니다 cm이다. 중요한 할 수 입니다.dict
기본방법이, 수 있습니다. 즉, 키, 즉 , 예를 들면 키, 즉 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 키, 이런 것들이 있습니다.get
,pop
,items
syslog.
class DotDictMeta(type):
def __new__(
cls,
name,
bases,
attrs,
rename_method=lambda n: f'__{n}__',
**custom_methods,
):
d = dict
attrs.update(
cls.get_hidden_or_renamed_methods(rename_method),
__getattr__=d.__getitem__,
__setattr__=d.__setitem__,
__delattr__=d.__delitem__,
**custom_methods,
)
return super().__new__(cls, name, bases, attrs)
def __init__(self, name, bases, attrs, **_):
super().__init__(name, bases, attrs)
@property
def attribute_error(self):
raise AttributeError
@classmethod
def get_hidden_or_renamed_methods(cls, rename_method=None):
public_methods = tuple(
i for i in dict.__dict__.items() if not i[0].startswith('__')
)
error = cls.attribute_error
hidden_methods = ((k, error) for k, v in public_methods)
yield from hidden_methods
if rename_method:
renamed_methods = ((rename_method(k), v) for k, v in public_methods)
yield from renamed_methods
class DotDict(dict, metaclass=DotDictMeta):
pass
DotDict 네임스페이스에서 dict 메서드를 삭제하고 dict 클래스 메서드를 계속 사용할 수 있습니다.다른 dict 인스턴스에서 동작하고 DotDict 여부를 추가로 확인하지 않고 동일한 메서드를 사용하는 경우에도 유용합니다.
dct = dict(a=1)
dot_dct = DotDict(b=2)
foo = {c: i for i, c in enumerate('xyz')}
for d in (dct, dot_dct):
# you would have to use dct.update and dot_dct.__update methods
dict.update(d, foo)
assert dict.get(dot, 'foo', 0) is 0
언급URL : https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary
'programing' 카테고리의 다른 글
PIL 이미지를 NumPy 어레이로 변환하는 방법 (0) | 2022.09.30 |
---|---|
원격 연결이 간헐적임 (0) | 2022.09.30 |
php 실행 파일 경로 php.validate를 설정하는 방법.php가 도커 컨테이너 내에 설정되어 있는 경우 vscode에서 executablePath를 사용할 수 있습니까? (0) | 2022.09.29 |
char 배열이 null로 종료되는 것이 보증됩니까? (0) | 2022.09.29 |
Java에서 와일드카드 문자열과 일치하는 파일을 찾으려면 어떻게 해야 합니까? (0) | 2022.09.29 |