2012-09-14 2 views
5

을 통해 문서는 파이썬 3.2를 반복weakref 모듈의 WeakKeyDictionaryWeakValueDictionary이 용기 반복에 메모를 가지고 :안전하게 WeakKeyDictionary 및 WeakValueDictionary

참고 :주의 : WeakKeyDictionary는에 내장되어 있기 때문에 Python 사전의 맨 위에있는 경우, 반복 할 때 크기를 변경하면 안됩니다. WeakKeyDictionary를 보장하기가 어려울 수 있습니다. 반복되는 동안 프로그램에서 수행 한 작업으로 인해 사전에있는 항목이 "마법에 의해"사라집니다 (가비지 수집의 부작용).

이 컨테이너의 동작을 지정하는 것이 다소 어려울 것 같습니다. 특히 CPython의 가비지 컬렉터를 사용하는 코드 (사이클이 포함 된 데이터 구조를 사용하는 경우) 또는 다른 Python 구현 (예 : 자이 썬)을 사용하는 경우 이러한 컬렉션을 반복하는 안전한 방법이없는 것처럼 들립니다.

가비지 수집기가 프로그램의 어느 지점에서든 참조를 지울 수있을 때 어떻게 안전하게 이러한 컬렉션을 반복 할 수 있습니까? CPython에 대한 솔루션을 갖는 것이 가장 중요하지만 다른 구현에서도이 문제에 관심이 있습니다.

아마도 WeakKeyDictionary를 반복하는 안전한 방법일까요?

import weakref 

d = weakref.WeakKeyDictionary() 

... 

for k, v in list(d.items()): 
    ... 

답변

6

안전을 위해 어딘가에서 참조를 유지해야합니다. 관용구를 사용 :이 목록은 가비지 수집 될 수있는 루프의 마지막 반복하는 동안, 대부분의 시간을 작동해도 때문에

for k,v in list(d.items()): 

이 완전히 안전하지 않습니다.

올바른 방법은 다음과 같습니다

items = list(d.items()) 
for k,v in items: 
    #do stuff that doesn't have a chance of destroying "items" 
del items 

당신이 WeakValueDictionary를 사용하는 경우 단순히 키를 저장하고, 값을 저장 할 수있는 WeakKeyDictionary를 사용하는 경우.

참고 : python2에서 .items()은 이미 목록을 반환합니다.

결국 궁극적으로 "안전"이란 무엇을 의미합니까? 당신은 단순히 반복이 제대로 진행 것을 의미한다면, (모든 요소를 ​​한 번 반복) :

for k,v in list(d.items()): 

안전, 사전을 통해 반복 실제로 list(d.items())에 의해 수행되기 때문에, 당신은 단지 반복된다 명부.

대신, 반복 요소 중에 for -loop의 부작용으로 사전에서 "사라지다"고해서는 안되는 경우 루프의 끝까지 강력한 참조를 유지해야합니다. 루프를 시작하기 전에 변수에 목록을 저장해야합니다.

+2

첫 번째 예제가 안전하지 않은 이유는 무엇입니까? 목록에는 각 키와 값에 대한 강력한 참조가 포함될 것이며 마지막 반복에서'k'와'v'는 내가 관심있는 객체에 대한 강력한 참조를 보유합니다. 따라서 목록은 마지막 반복이 종료되기 전에 가비지 수집 될 수 있습니다. 그게 맞습니까? – Feuermurmel

+0

'k와 v'는 객체에 대한 강력한 참조를 유지하기 때문에'for k, d.items()의 v '는 안전하다고 말하는 것과 같습니다.for-loop 내부에서'k'와'v'가 삭제 될 확률이 있다면 반복은 안전하지 않습니다. 간단한 작업을 위해서'WeakKeyDictionary'를 반복하는 것이 안전해야합니다. – Bakuriu

+3

아마도 나는 뭔가를 오해하고있을 것입니다. 그러나 객체'k'와'v' 참조는 어떻게 삭제 될 수 있습니까? 이러한 변수가 범위에 있고 지나치게 사용되지 않는 한 참조 된 객체는 안전합니다. 아니면 마지막 반복에서 해당 객체에 대한 모든 강력한 참조를 제거하는 것에 대해 이야기하고 있습니까? 이는 사전을 변경하지만 반복이 시작된 후에 사전에 액세스하지 않으므로 안전하지 않습니다. 마지막 반복 과정에서 잘못 될 수있는 것을 보여줄 수 있습니까? – Feuermurmel

관련 문제