Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 약한 참조(Weak Reference) 완벽 정리 – weakref 모듈 사용법과 예제

파이썬에서 약한 참조(Weak Reference)를 생성하려면 weakref 모듈을 사용해야 합니다. 약한 참조는 객체를 메모리에 계속 유지시키지 않으면서 해당 객체에 접근할 수 있게 해주는 기능입니다. 약한 참조의 대표적인 활용 사례로는 대용량 객체를 위한 캐시(cache)나 매핑(mapping) 구현이 있습니다.

이 모듈을 사용하려면 먼저 아래와 같이 임포트해야 합니다.

import weakref

주의할 점은 모든 객체가 약한 참조를 지원하는 것은 아니라는 것입니다. 예를 들어 tuple, int 같은 일부 내장 타입은 약한 참조를 지원하지 않습니다. 이제 weakref 모듈에서 제공하는 주요 클래스와 메서드를 살펴보겠습니다.

클래스 weakref.ref(object[, callback])

이 클래스는 객체에 대한 약한 참조를 반환합니다. 참조 대상 객체가 아직 살아 있다면, 참조 객체를 호출하여 실제 객체를 가져올 수 있습니다. 반면, 원본 객체가 이미 소멸되었다면 None을 반환합니다.

메서드 weakref.proxy(object[, callback])

이 메서드는 약한 참조를 사용하는 객체의 프록시(proxy)를 반환합니다. 반환된 객체는 ProxyType 또는 CallableProxyType 중 하나입니다. 프록시를 사용하면 원본 객체처럼 직접 속성에 접근하고 메서드를 호출할 수 있습니다.

메서드 weakref.getweakrefcount(object)

이 메서드는 특정 객체에 연결된 약한 참조 및 프록시의 개수를 반환합니다.

메서드 weakref.getweakrefs(object)

이 메서드는 특정 객체에 연결된 약한 참조 및 프록시 객체들의 목록을 리스트 형태로 반환합니다.

예제 코드

import weakref
class my_list(list):
   pass
new_list = my_list('String') #my_list 클래스로 리스트 정의
print(new_list)
weak_ref = weakref.ref(new_list)
new_weak_list = weak_ref()
new_proxy = weakref.proxy(new_list)
print(new_weak_list)
print('프록시를 통해 접근한 객체: ' + str(new_proxy))
if new_list is new_weak_list:
   print("약한 참조가 존재합니다")
print('약한 참조 개수: ' + str(weakref.getweakrefcount(new_list)))
del new_list, new_weak_list #두 객체 삭제
print("약한 참조 값: " + str(weak_ref()))

실행 결과

['S', 't', 'r', 'i', 'n', 'g']
['S', 't', 'r', 'i', 'n', 'g']
프록시를 통해 접근한 객체: ['S', 't', 'r', 'i', 'n', 'g']
약한 참조가 존재합니다
약한 참조 개수: 2
약한 참조 값: None

예제 코드 설명

위 예제에서는 list를 상속받은 my_list 클래스를 정의하고, 이를 이용해 문자열 'String'으로 리스트를 생성했습니다. 그다음 weakref.ref()로 약한 참조를 만들고, 참조를 호출하여 실제 객체를 얻어냈습니다. 또한 weakref.proxy()를 통해 프록시 객체도 생성했습니다.

getweakrefcount() 결과가 2인 이유는 약한 참조(weak_ref)와 프록시(new_proxy) 두 개가 모두 new_list 객체에 연결되어 있기 때문입니다.

마지막으로 del 키워드로 원본 객체와 약한 참조로 얻은 객체를 삭제하면, 더 이상 해당 객체를 참조하는 곳이 없으므로 가비지 컬렉터가 메모리를 회수합니다. 이후 약한 참조를 다시 호출하면 객체가 존재하지 않기 때문에 None이 출력되는 것을 확인할 수 있습니다. 이것이 바로 약한 참조의 핵심 동작 방식입니다.