파이썬에서 __weakref__는 정확히 무엇입니까?
놀랍게도에 대한 명시적인 문서가 없습니다 __weakref__
. 약한 참조는 여기 에 설명되어 있습니다 . __weakref__
의 문서에서도 곧 언급됩니다 __slots__
. 그러나 나는 __weakref__
그 자체 에 대해 아무것도 찾을 수 없었다 .
정확히 무엇입니까 __weakref__
? -플래그 역할을하는 멤버 일뿐 : 존재하는 경우 개체가 약하게 참조 될 수 있습니까? -아니면 원하는 동작을 얻기 위해 재정의 / 할당 할 수있는 함수 / 변수입니까? 어떻게?
__weakref__
현재 개체에 대한 모든 약한 참조를 참조하는 불투명 한 개체입니다. 실제로 는 객체에 대한 약한 참조이자 해당 객체에 대한 모든 약한 참조에 대한 이중 연결 목록의 일부인 인스턴스 weakref
(또는 때때로 weakproxy
)입니다.
가비지 수집기가 참조 대상이 수집되었음을 약한 참조에 알리고 더 이상 기본 포인터에 대한 액세스를 허용하지 않도록하는 구현 세부 사항 일뿐입니다.
약한 참조는 참조하는 객체의 참조 횟수를 확인하는 데 의존 할 수 없습니다. 이는 해당 메모리가 회수되어 현재 다른 개체에서 사용 중일 수 있기 때문입니다. VM이 충돌하는 최상의 시나리오, 최악의 경우 약한 참조가 원래 참조하지 않았던 개체에 대한 액세스를 허용합니다. 이것이 가비지 수집기가 약한 참조에 해당 참조가 더 이상 유효하지 않음을 알려야하는 이유입니다.
구조에 대해서는 weakrefobject.h 를 참조 하고이 개체에 대한 C-API를 참조하십시오 . 그리고 구현 세부 사항은 여기에 있습니다
[편집 1 : 링크드리스트의 성격과 약한 참조가 언제 재사용되는지 설명]
흥미롭게도 공식 문서 는이 주제에 대해 다소 이해하기 어렵습니다.
__weakref__
각 인스턴스에 대한 변수가 없으면 정의하는 클래스__slots__
는 해당 인스턴스에 대한 약한 참조를 지원하지 않습니다. 약한 참조 지원이 필요한__weakref__
경우__slots__
선언 의 문자열 시퀀스에 추가 합니다 .
type
객체 문서 주제에 너무 많이 따라 도움말 일하지 않는 것 :
유형의
__slots__
선언에라는__weakref__
슬롯이 포함 되면 해당 슬롯은 유형 인스턴스의 약한 참조 목록 헤드가되고 슬롯의 오프셋은 유형의tp_weaklistoffset
.
약한 참조는 연결 목록을 형성합니다. 해당 목록의 헤드 (객체에 대한 첫 번째 약한 참조)는를 통해 사용할 수 있습니다 __weakref__
. Weakref는 가능할 때마다 재사용되므로 목록 (Python 목록이 아닙니다!)은 일반적으로 비어 있거나 단일 요소를 포함합니다.
예 :
를 처음 사용할 때 weakref.ref()
대상 개체에 대한 새로운 약한 참조 체인을 만듭니다. 이 체인의 헤드는 새로운 weakref이며 대상 객체의 __weakref__
:
>>> import weakref
>>> class A(object): pass
>>> a = A()
>>> b = weakref.ref(a)
>>> c = weakref.ref(b)
>>> print(b is c is a.__weakref__)
True
보시다시피, b
재사용됩니다. 예를 들어 콜백 매개 변수를 추가하여 파이썬이 새로운 weakref를 생성하도록 강제 할 수 있습니다.
>>> def callback():
>>> pass
>>> a = A()
>>> b = weakref.ref(a)
>>> c = weakref.ref(b, callback)
>>> print(b is c is a.__weakref__)
False
이제 b is a.__weakref__
, c
은 체인의 두 번째 참조입니다. 참조 체인은 Python 코드에서 직접 액세스 할 수 없습니다. 체인의 헤드 요소 ( b
) 만 볼 수 있지만 체인이 계속되는 방식 ( b
-> c
)은 볼 수 없습니다.
__weakref__
객체에 대한 모든 약한 참조의 내부 링크 목록의 머리도 마찬가지 입니다. 이 역할 __weakref__
이 간결하게 설명 된 공식 문서를 찾을 수 없으므로 구현 세부 사항이므로이 동작에 의존해서는 안됩니다.
__weakref__
변수는 객체가 약한 참조를 지원 객체 약한 참조를 보존 할 수있게하는 속성이다.
파이썬 문서는 다음과 같이 설명했습니다.
참조에 대한 나머지 참조가 약한 참조 일 때 가비지 수집은 참조를 파괴하고 다른 것에 메모리를 재사용 할 수 있습니다.
따라서 약한 참조의 의무는 객체의 유형과 범위에 관계없이 가비지 수집이 가능하도록 객체에 대한 조건을 제공하는 것입니다.
에 대해 __slots__
먼저 문서를 살펴볼 수 있습니다.이 문서는 매우 잘 설명합니다.
기본적으로 클래스 인스턴스에는 속성 저장을위한 사전이 있습니다. 이것은 인스턴스 변수가 거의없는 객체를위한 공간을 낭비합니다. 많은 수의 인스턴스를 생성 할 때 공간 소비가 급증 할 수 있습니다.
기본값은
__slots__
클래스 정의에서 정의 하여 재정의 할 수 있습니다 .__slots__
선언 각 변수에 대한 값을 유지하도록 각각의 인스턴스 인스턴스 변수 보유 충분한 공간의 시퀀스 걸린다.__dict__
각 인스턴스에 대해 생성되지 않기 때문에 공간이 절약 됩니다.
이제 사용하여 이후 __slots__
귀하의 속성에 대한 요구 저장 장치를 제어합니다 당신을, 사실의 자동 생성을 방지 __dict__
하고 __weakref__
각 인스턴스에 대해. __weakref__
약한 참조를 처리하기 위해 각 개체의 필수 변수는 무엇 입니까 ?
또한 이러한 모든 문서 외에도 object.__slots__
클래스에 대한 내용 은 다음과 같습니다.
이 클래스 변수에는 인스턴스에서 사용하는 변수 이름이있는 문자열, 반복 가능 또는 문자열 시퀀스가 할당 될 수 있습니다.
__slots__
선언 된 변수를위한 공간을 예약__dict__
하고__weakref__
각 인스턴스에 대한 및 자동 생성을 방지합니다 .
즉 __slots__
, 저장소 할당을 수동으로 관리하기위한 것이며 저장소와 __weakref__
관련된 개체에 대한 약한 참조를 허용하는 라이센스 (가비지 수집 기능 때문에)이므로 as __slots__
를 제어 할 수 __weakref__
있습니다. __dict__
속성 을 제어 합니다.
또한 문서는 사용과 함께 약한 참조를 지원하는 객체를 만드는 방법을 보여줍니다 __slots__
.
__weakref__
각 인스턴스에 대한 변수가 없으면 정의하는 클래스__slots__
는 해당 인스턴스에 대한 약한 참조를 지원하지 않습니다. 약한 참조 지원이 필요한'__weakref__'
경우__slots__
선언 의 문자열 시퀀스에 추가 합니다 .
다음은 Python 3.X의 예입니다.
>>> class Test:
... __slots__ = ['a', 'b']
...
>>>
>>> import weakref
>>>
>>> t = Test()
>>>
>>> r = weakref.ref(t)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create weak reference to 'Test' object
>>>
>>> class Test:
... __slots__ = ['a', 'b', '__weakref__']
...
>>> t = Test()
>>> r = weakref.ref(t)
>>>
>>> t.__weakref__
<weakref at 0x7f735bc55d68; to 'Test' at 0x7f735bc51fc8>
그러나 python 2.7에서는 문서가 앞서 언급 한 문서와 비슷하지만 이름에 __weakref__
변수를 제공하지 않는 인스턴스에서 약한 참조를 만들면 다음이 발생하지 않습니다 .__slots__
TypeError
>>> class Test:
... __slots__ = ['a', 'b']
...
>>> t = Test()
>>>
>>> r = weakref.ref(t)
>>>
>>> r
<weakref at 0x7fe49f4185d0; to 'instance' at 0x7fe4a3e75f80>
참조 URL : https://stackoverflow.com/questions/36787603/what-exactly-is-weakref-in-python
'development' 카테고리의 다른 글
Git 오류 : 이전 rebase 디렉토리 .git / rebase-apply가 여전히 존재하지만 mbox가 제공됨 (0) | 2020.12.30 |
---|---|
다 대다 필드를 직렬화하는 Django 나머지 프레임 워크 (0) | 2020.12.30 |
Perl에서 stderr, stdout 및 종료 코드를 한꺼번에 캡처하는 방법은 무엇입니까? (0) | 2020.12.30 |
java.exe -jar로 내 jar를 실행하는 동안 NoClassDefFoundError가 발생했습니다… 무엇이 잘못 되었나요? (0) | 2020.12.29 |
URL의 URL 인코딩 슬래시 (0) | 2020.12.29 |