, 다음 DICT가 자동으로 "dottable"이 될 것입니다. self.__dict__ = {}
을 설정하여 "도트 - 어빌리티"를 끌 수 있습니다. 그러나 색인 생성을 통해 키 - 값 쌍에 계속 액세스 할 수 있습니다. 이 아이디어는 katrielalex's bio page에서 주로 제공 :
class DottableDict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.__dict__ = self
def allowDotting(self, state=True):
if state:
self.__dict__ = self
else:
self.__dict__ = dict()
d = DottableDict()
d.allowDotting()
d.foo = 'bar'
print(d['foo'])
# bar
print(d.foo)
# bar
d.allowDotting(state=False)
print(d['foo'])
# bar
print(d.foo)
# AttributeError: 'DottableDict' object has no attribute 'foo'
그러나 파이썬의 선을, 기억
는
one-- 과 그것을 할 바람직 하나 --obvious 방법이 있어야합니다.
DICT 액세스를위한 표준 문법에 자신을 제한함으로써, 당신은 자신과 다른 사람에 대한 가독성/유지 보수를 향상시킬 수 있습니다.
작동 원리 : 당신이 d.foo
를 입력하면, 파이썬은 d.__dict__
에 하나의 장소의 숫자에 'foo'
을 찾습니다
. (또한 d.__class__.__dict__
을보고 d.__class__.mro()
에 나열된 모든 기지의 모든 __dict__
... 속성 조회에 대한 자세한 내용은 excellent article by Shalabh Chaturvedi을 참조하십시오.
어쨌든 중요한 점은 d.__dict__
에있는 모든 키 - 값 쌍에 점 표기법으로 액세스 할 수 있다는 것입니다.
사실은 우리가 d
자체에 d.__dict__
을 설정하여 d
의 키 - 값 쌍에 도트 액세스 할 수 있습니다 의미! 결국 d
은 dict이며, d.__dict__
은 dict-like 오브젝트를 기대합니다. 이것은 또한 메모리 효율적임을 주목하십시오. 우리는 어떤 키 - 값 쌍도 복사하지 않고 이미 존재하는 dict에 d.__dict__
을 지시하는 것을 간략히하고 있습니다.
d.__dict__
을 dict()
에 할당함으로써 d
의 키 - 값 쌍에 대한 도트 액세스를 효과적으로 해제합니다. (이것은 완전하게 비활성화 점 액세스하지 않습니다 -. 예를 들어 d.__class_.__dict__
에서 키 - 값 쌍을 여전히 점 표기법을 통해 액세스 사실 다행하거나 다시 allowDotting
메소드를 호출 할 수 없을 것입니다 수 있습니다!)
이제 d
에서 모든 키 - 값 쌍을 삭제하는지 궁금 할 것입니다. 내 대답은 아니오 야.
키 - 값 쌍은 __dict__
속성에 저장되지 않습니다. 실제로 일반 dict에는 __dict__
특성이 없습니다.따라서 d.__dict__ = {}
을 설정하면 dict이 중립 조건으로 재설정됩니다. 우리는 너무
self.__dict__ = dict()
의
del self.__dict__
insteaad을 사용했을 수 있습니다. 그러나 DottableDict
에 __dict__
속성이 부여되었으므로 DottableDict
의 인스턴스에 항상 __dict__
속성을 허용하는 것이 더 깨끗해 보입니다. 코멘트에서
당신은주의 :
는
단계 : 액세스를 설정, 액세스, '바'로 설정 d.foo을 해제 d.foo는 사방에서 사라졌다. allowDotting
동안 설정 한 같은 d.foo
같은
유지하기 위해 속성이 해제되어, 당신은 대체 DICT이있는 self.__dict__
설정 한에 저장해야합니다.
class DottableDict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self['_attributes'] = dict()
self.allowDotting()
def allowDotting(self, state=True):
if state:
self.update(self['_attributes'])
self.__dict__ = self
else:
self.__dict__ = self['_attributes']
d = DottableDict()
d.allowDotting(state=False)
d.foo = 'bar'
d.allowDotting(state=True)
print(d.foo)
# bar
d.allowDotting(state=False)
print(d.foo)
# bar
d.allowDotting(state=True)
print(d.foo)
# bar
종래의 단일 밑줄로 시작하는 속성은 개인 구현 세부 정보로 이해됩니다. 개인 키 ('_attribute'
)를 사용하여 컨벤션을 확장합니다.
원하는 동작은 무엇입니까? – unutbu
가끔 사전 [도트 - 액세스]를 사용하는 대신 인스턴스 [ 'foo']의 대안으로 instance.foo를 통해 dict 파생 인스턴스 값에 액세스하는 것을 좋아하지만 런타임시이 기능을 켜고 끌 수 있어야합니다. –