파이썬에서 dir과 __dict__의 가장 큰 차이점은 무엇입니까
class C(object):
def f(self):
print self.__dict__
print dir(self)
c = C()
c.f()
산출:
{}
['__class__', '__delattr__','f',....]
self .__ dict__에 'f'가없는 이유
dir()
찾는 것 이상을합니다 __dict__
우선 , 객체의 속성을 조회하는 dir()
것과 같은 속성을 사용하는 방법을 알고있는 API 메소드입니다 __dict__
.
__dict__
하지만 모든 개체에 속성 이있는 것은 아닙니다 . 예를 들어 사용자 지정 클래스에 __slots__
속성 을 추가하는 경우 해당 클래스의 인스턴스에는 __dict__
속성이 없지만 dir()
해당 인스턴스에서 사용 가능한 속성을 계속 나열 할 수 있습니다.
>>> class Foo(object):
... __slots__ = ('bar',)
... bar = 'spam'
...
>>> Foo().__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__dict__'
>>> dir(Foo())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar']
많은 내장 유형에도 동일하게 적용됩니다. list
에 __dict__
속성이 없지만 다음을 사용하여 모든 속성을 나열 할 수 있습니다 dir()
.
>>> [].__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'
>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
어떤 dir()
경우에 수행
Python 인스턴스에는 고유 한이 __dict__
있지만 클래스도 있습니다.
>>> class Foo(object):
... bar = 'spam'
...
>>> Foo().__dict__
{}
>>> Foo.__dict__.items()
[('__dict__', <attribute '__dict__' of 'Foo' objects>), ('__weakref__', <attribute '__weakref__' of 'Foo' objects>), ('__module__', '__main__'), ('bar', 'spam'), ('__doc__', None)]
이 dir()
메서드는 이러한 속성 과 하나의 속성을 모두 사용 하여 인스턴스, 클래스 및 클래스의 모든 조상에서 사용 가능한 속성의 전체 목록을 만듭니다.__dict__
object
클래스에 속성을 설정하면 인스턴스에도 다음이 표시됩니다.
>>> f = Foo()
>>> f.ham
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'ham'
>>> Foo.ham = 'eggs'
>>> f.ham
'eggs'
속성이 클래스에 추가되기 때문입니다 __dict__
.
>>> Foo.__dict__['ham']
'eggs'
>>> f.__dict__
{}
인스턴스 __dict__
가 어떻게 비어 있는지 확인하십시오 . Python 객체에 대한 속성 조회는 속성을 검색하기 위해 인스턴스에서 유형, 부모 클래스까지 객체의 계층 구조를 따릅니다.
인스턴스에서 직접 속성을 설정하는 경우에만 __dict__
클래스 __dict__
가 변경되지 않은 상태로 유지 되는 동안 인스턴스에 반영된 속성을 볼 수 있습니다 .
>>> f.stack = 'overflow'
>>> f.__dict__
{'stack': 'overflow'}
>>> 'stack' in Foo.__dict__
False
TLDR; or the summary
dir()
doesn't just look up an object's __dict__
(which sometimes doesn't even exist), it will use the object's heritage (its class or type, and any superclasses, or parents, of that class or type) to give you a complete picture of all available attributes.
An instance __dict__
is just the 'local' set of attributes on that instance, and does not contain every attribute available on the instance. Instead, you need to look at the class and the class's inheritance tree too.
The function f
belongs to the dictionary of class C
. c.__dict__
yields attributes specific to the instance c
.
>>> class C(object):
def f(self):
print self.__dict__
>>> c = C()
>>> c.__dict__
{}
>>> c.a = 1
>>> c.__dict__
{'a': 1}
C.__dict__
would yield attributes of class C
, including function f
.
>>> C.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'C' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None, 'f': <function f at 0x0313C1F0>})
While an object can refer to an attribute of its class (and indeed all the ancestor classes), the class attribute so referred does not become part of the associated dict itself. Thus while it is legitimate access to function f
defined in class C
as c.f()
, it does not appear as an attribute of c
in c.__dict__
.
>>> c.a = 1
>>> c.__dict__
{'a': 1}
'development' 카테고리의 다른 글
Clojure에서 맵 키와 값을 반복하는 방법은 무엇입니까? (0) | 2020.12.04 |
---|---|
AES 암호화-키 대 IV (0) | 2020.12.04 |
IIS는 시작된 URL과 일치하는 웹 사이트를 나열하지 않습니다. (0) | 2020.12.04 |
자바 스크립트에서 타입 스크립트 선언 파일 생성 (0) | 2020.12.04 |
메이븐 프로젝트를 Dockerize하는 방법? (0) | 2020.12.04 |