Python Weak Ref
FrontPage|FindPage|TitleIndex|RecentChanges|UserPreferences E D R S I M H RSS

python.or.kr 에서 2.1 에서 달라진점 문서에서 가져옴

2. 약한 참조(Weak Reference)의 지원 약한참조(weak reference)란 무엇인가? weak reference란 레퍼런스 카운트로 셈되지 않는 레퍼런스이다. 객체에 약한 참조를 제외하고 다른 레퍼런스가 존재하지 않게되면, 그 객체는 해제(release)되고 모든 약한 참조는 정의된지 않은 상태로 바뀐다.

약한참조(weak reference)는 왜 필요한가? 이러한 내용은 순환적인 참조에 사용될 수 있다. 순환 참조는 쓰레기 수집을 방해하는 주요한 문제였다. 2.0에서는 주기적으로 순환참조를 검사해서 쓰레기 수집을 하는 기능이 추가되었지만, 자주 하게되면 엄청난 쓸데없는 CPU자원을 낭비하는 것이고 자주 하지 않게 되면 많은 해제되어야할 순환 참조되는 객체들이 메모리에 존재할 수 있다. 실제로 DOM 응용에서는 순환참조가 무수히 발생한다고 한다. 이것을 해결하기 위한 것이 약한참조(weak reference)이다. 또한, 약한 참조는 다양한 인스턴스들 사이에서 공유되는 객체를 참조하는데도 사용될 수 있다.

약한 사전(Weak dictionary)이란? 캐쉬(Caches)라고도 한다. 약한 사전은 값으로 약한 참조를 가지고 있는 사전을 말한다. 일반적인 사전과 같지만 다음과 같은 차이점이 있다.

값으로 약한 참조가 가능한 객체를 받아들인다. 값으로 치환된 내용은 약한 참조된다. 객체가 삭제되면 자동적으로 캐쉬에 있는 키,값 쌍도 삭제된다.

그럼 약한 참조가 가능한 객체는 어떤 것인가? 모든 객체에 대해서 약한 참조가 가능하지는 않다. 실제적인 메모리 크기를 갖고 있거나, 외부 자원으로 참조(데이터 베이스 연결, 오픈 파일 객체등)를 가지고 있는 경우가 가능하다. 예를 들면, ..

.... (예 추가.)

약한 참조 모듈 weakref weakref.ref()는 약한 참조 객체를 생성한다. 약한 참조는 쓰레기 수집되지 않은 객체를 참조하고, 실제로 그 객체가 메모리에 있는지 조사하는데도 사용된다. 레퍼런스 객체를 호출하여 레퍼런스를 검색(retrieve)한다. 레퍼런스가 더 이상 존재하지 않으면, None을 대신 리턴한다. weakref.mapping()은 약한 사전을 생성한다.

임의의 키를 값에 매핑한다. 그러나, 값에 대한 참조를 소유하지 않는다. 그 값이 사라지게 되면, (key, value) 쌍은 모든 사전에서 제거된다. 사전과 같이 약한 사전은 해쉬가능하지 않다. weakref.proxy()는 원래의 객체와 유사하게 동작하는 프록시 객체를 생성한다.

프록시 객체란, 원래의 객체와 유사하게 동작하려고 하는 약한 참조이다. 해쉬 가능하지 않다. 참조가 없어진 후에 연산을 수행하면 weakref.?ReferenceError 예외가 발생한다. "is", type() 및 id()를 사용할 수 있다.

실제적인 코드는 되지 못하지만, 동작 특성을 볼 수 있도록 예를 다음에 보인다.

weakref.ref 예제:
>>> import sys 
>>> import weakref 
>>> class Foo:pass 
  
>>> f = Foo() 
>>> r = weakref.ref(f) 
>>> r 
<weakref at 0xbb59fc; to 'instance' at 0xbae09c> 
>>> r() 
<__main__.Foo instance at 00BAE09C> 
>>> f 
<__main__.Foo instance at 00BAE09C> 
>>> sys.getrefcount(f) # 레퍼런스 카운트 값 읽어보기 
2    # 실제로는 1이다. getrefcount 함수로 인해 1이 추가되어있기 때문이다. 
>>> g = f 
>>> sys.getrefcount(f) 
3 
>>> del g 
>>> del f 
>>> r 
<weakref at bb59fc; dead> 
>>> r() 
weakref.mapping 예제:
>>> f = Foo() 
>>> sys.getrefcount(f) 
2 
>>> d = weakref.mapping()    # weakref용 사전을 얻음 
>>> sys.getrefcount(f) 
2 
>>> d['f'] = f        # weak reference 가능한 객체를 값으로 넘겨야함. 
>>> sys.getrefcount(f)    # 레퍼런스 카운트 변화 없음. 
2 
>>> f = Foo() 
>>> d = weakref.mapping() 
>>> d['f'] = f 
>>> d['f'] 
<__main__.Foo instance at 01259FDC> 
>>> f 
<__main__.Foo instance at 01259FDC> 
>>> del f 
>>> len(d) 
1 
>>> d.items() 
[] 
>>> len(d) 
0 
weakref.proxy 예제:

.........................

EditText|FindPage|DeletePage|LikePages| Valid XHTML 1.0! Valid CSS! powered by MoniWiki