Programing

파이썬 클래스의 __dict __.__ dict__ 속성은 무엇입니까?

crosscheck 2020. 10. 8. 07:43
반응형

파이썬 클래스의 __dict __.__ dict__ 속성은 무엇입니까?


>>> class A(object): pass
... 
>>> A.__dict__
<dictproxy object at 0x173ef30>
>>> A.__dict__.__dict__
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
AttributeError: 'dictproxy' object has no attribute '__dict__'
>>> A.__dict__.copy()
{'__dict__': <attribute '__dict__' of 'A' objects> ... }
>>> A.__dict__['__dict__']
<attribute '__dict__' of 'A' objects> # What is this object?

내가 그렇게 A.something = 10하면 A.__dict__. 무엇 이다<attribute '__dict__' of 'A' objects>에서 발견이 A.__dict__.__dict__뭔가를 포함 않을 때, 그리고?


우선는와 A.__dict__.__dict__다르며 A.__dict__['__dict__']전자는 존재하지 않습니다. 후자는 __dict__클래스의 인스턴스가 가질 수 있는 속성입니다. 특정 인스턴스에 대한 속성의 내부 사전을 반환하는 설명자 개체입니다. 간단히 말해, __dict__객체 속성은 객체의에 저장할 수 없으므로 __dict__클래스에 정의 된 설명자를 통해 액세스됩니다.

이를 이해하려면 디스크립터 프로토콜 문서 를 읽어야합니다 .

짧은 버전 :

  1. 클래스 인스턴스의 경우에 대한 A액세스 instance.__dict__가 제공 A.__dict__['__dict__']됩니다 vars(A)['__dict__'].
  2. 클래스 A의 경우에 대한 액세스 A.__dict__type.__dict__['__dict__'](이론상) vars(type)['__dict__'].

긴 버전 :

클래스와 객체 모두 속성 연산자 (클래스 또는 메타 클래스를 통해 구현 __getattribute__됨)와에서 사용하는 __dict__속성 / 프로토콜을 통해 속성에 대한 액세스를 제공합니다 vars(ob).

일반 객체의 경우 __dict__객체 dict는 속성을 저장 하는 별도 객체를 만들고 __getattribute__먼저 액세스를 시도하고 거기에서 속성을 가져옵니다 (설명자 프로토콜을 사용하여 클래스에서 속성을 찾고를 호출하기 전에 __getattr__). __dict__클래스 설명자는이 사전에 대한 액세스를 구현합니다.

  • x.name위해 사람들을 시도하는 것과 같습니다 x.__dict__['name'], type(x).name.__get__(x, type(x)),type(x).name
  • x.__dict__ 동일하지만 명백한 이유로 첫 번째는 건너 뜁니다.

__dict__of instance__dict__인스턴스에 저장할 수 없기 때문에 설명자 프로토콜을 통해 직접 액세스하고 인스턴스의 특수 필드에 저장합니다.

클래스의 경우에도 유사한 시나리오가 적용되지만 __dict__, 사전 인 척하는 특수 프록시 개체 (내부적으로는 아닐 수 있음)이며이를 변경하거나 다른 것으로 대체 할 수 없습니다. 이 프록시를 사용하면 다른 무엇보다도 자신에게 고유하고 해당베이스 중 하나에 정의되지 않은 클래스의 속성에 액세스 할 수 있습니다.

기본적으로 vars(cls)비어있는 클래스의 a 는에서 내부적으로 사용 __dict__하는 인스턴스의 속성 과 클래스의 독 스트링 을 저장하기위한 세 개의 설명자를 전달 합니다. 정의하면 처음 두 개는 사라질 수 있습니다 . 그러면 속성이 없지만 대신 각 슬롯에 대해 단일 클래스 속성이 있습니다. 그러면 인스턴스의 속성이 사전에 저장되지 않고 클래스의 각 설명자가 액세스 할 수 있습니다.__weakref__weakref__slots____dict____weakref__


그리고 마지막으로, 불일치 A.__dict__다른는 A.__dict__['__dict__']속성이 있기 때문입니다 __dict__입니다, 예외로, 결코 에서 보지 않았다 vars(A)그래서 무엇 마찬가지입니다 것은 당신이 사용하는 거라고 거의 모든 다른 속성에 대한 사실이 아니다. 예를 들어 A.__weakref__A.__dict__['__weakref__']. 이 불일치가 존재하지 않으면 사용 A.__dict__이 작동하지 않으며 항상 vars(A)대신 사용해야 합니다.


속성을 A.__dict__저장하는 딕셔너리 이므로 동일한 속성에 대한 직접 참조 입니다.AA.__dict__['__dict__']A.__dict__

A.__dict__자신에 대한 (종류의) 참조를 포함합니다. "종류"부분은 표현식 이 일반 대신 A.__dict__a dictproxy반환하는 이유 dict입니다.

>>> class B(object):
...     "Documentation of B class"
...     pass
...
>>> B.__doc__
'Documentation of B class'
>>> B.__dict__
<dictproxy object at 0x00B83590>
>>> B.__dict__['__doc__']
'Documentation of B class'

탐험을 좀 해보자!

>>> A.__dict__['__dict__']
<attribute '__dict__' of 'A' objects>

그게 뭔지 궁금 해요?

>>> type(A.__dict__['__dict__'])
<type 'getset_descriptor'>

What attributes does a getset_descriptor object have?

>>> type(A.__dict__["__dict__"]).__dict__
<dictproxy object at 0xb7efc4ac>

By making a copy of that dictproxy we can find some interesting attributes, specifically __objclass__ and __name__.

>>> A.__dict__['__dict__'].__objclass__, A.__dict__['__dict__'].__name__
(<class '__main__.A'>, '__dict__')

So __objclass__ is a reference to A and __name__ is just the string '__dict__', name of an attribute perhaps?

>>> getattr(A.__dict__['__dict__'].__objclass__, A.__dict__['__dict__'].__name__) == A.__dict__
True

There we have it! A.__dict__['__dict__'] is an object that can refer back to A.__dict__.


You can try the following simple example to understand more of this:

>>> class A(object): pass
... 
>>> a = A()
>>> type(A)
<type 'type'>
>>> type(a)
<class '__main__.A'>
>>> type(a.__dict__)
<type 'dict'>
>>> type(A.__dict__)
<type 'dictproxy'>
>>> type(type.__dict__)
<type 'dictproxy'>
>>> type(A.__dict__['__dict__'])
<type 'getset_descriptor'>
>>> type(type.__dict__['__dict__'])
<type 'getset_descriptor'>
>>> a.__dict__ == A.__dict__['__dict__'].__get__(a)
True
>>> A.__dict__ == type.__dict__['__dict__'].__get__(A)
True
>>> a.__dict__ == type.__dict__['__dict__'].__get__(A)['__dict__'].__get__(a)
True

From the above example, it seems that class objects attributes are stored by their class, class's attributes are stored by their class, which are metaclasses. This is also validated by:

>>> a.__dict__ == A.__getattribute__(a, '__dict__')
True
>>> A.__dict__ == type.__getattribute__(A, '__dict__')
True

참고URL : https://stackoverflow.com/questions/4877290/what-is-the-dict-dict-attribute-of-a-python-class

반응형