파이썬 - 약한 참조

안녕하세요, 미래의 프로그래머 여러분! 오늘은 파이썬에서의 약한 참조의 흥미로운 세계에 빠지기 위해 준비되었습니다. 프로그래밍에 새로운 여러분이라면 걱정하지 마세요 – 저는 여러분을 단계별로 이 개념을 안내해 드릴 것입니다. 마치 저가 수년 동안 지도한 수많은 학생들을 위해 했던 것처럼요. 그럼, 함께 이 흥미로운 여정에 떠나보죠!

Python - Weak References

약한 참조는 무엇인가요?

자세히 이야기하기 전에, 약한 참조가 무엇인지 이해해 보겠습니다. 파티에 갔을 때 새로운 사람을 만났다고 생각해 보세요. 그들의 얼굴을 기억할 수는 있지만, 이름을 기억하지 못할 수도 있죠. 이 것이 파이썬에서의 약한 참조와 비슷합니다!

프로그래밍 용어로는, 약한 참조는 객체를 참조할 때 참조 횟수를 증가시키지 않도록 합니다. 이는 객체가 여전히 약한 참조가 가리키고 있어도 파이썬이 가비지 수거(정리)를 할 수 있음을 의미합니다.

간단한 예제를 살펴보겠습니다:

import weakref

class Party:
def __init__(self, name):
self.name = name

# Party 객체 생성
awesome_party = Party("Python Programmers' Bash")

# Party에 대한 약한 참조 생성
weak_party = weakref.ref(awesome_party)

# 약한 참조를 통해 객체에 접근
print(weak_party().name)  # 출력: Python Programmers' Bash

# 원래 객체 삭제
del awesome_party

# 다시 객체에 접근하려고 시도
print(weak_party())  # 출력: None

이 예제에서, Party 객체와 그에 대한 약한 참조를 생성합니다. 약한 참조를 통해 객체에 접근할 수 있지만, 원래 객체를 삭제하면 약한 참조는 None을 반환합니다.

콜백 함수

이제 콜백 함수를 추가하여 약한 참조를 더욱 흥미로워지게 만들어 보겠습니다. 이들은 객체가 가비지 수거될 때마다 행동하는 작은 도우미입니다.

import weakref

def party_over(reference):
print("The party is over! Time to clean up.")

class Party:
def __init__(self, name):
self.name = name

awesome_party = Party("Python Coders' Fiesta")
weak_party = weakref.ref(awesome_party, party_over)

del awesome_party
# 출력: The party is over! Time to clean up.

여기서, awesome_party 객체가 가비지 수거될 때 party_over 함수가 호출됩니다. 이는 파티 후에 정리를 알리는 책임감 있는 친구와 같습니다!

객체 정리

때로는 객체가 가비지 수거될 때마다 특정 작업을 수행하고 싶습니다. 이때는 정리자(finalizer)가 매우 유용합니다. 이들은 객체가永别하기 전의 마지막 인사와 같습니다.

import weakref

class Party:
def __init__(self, name):
self.name = name

def __del__(self):
print(f"Cleaning up after {self.name}")

awesome_party = Party("Python Picnic")
weak_party = weakref.ref(awesome_party)

del awesome_party
# 출력: Cleaning up after Python Picnic

이 예제에서, __del__ 메서드는 정리자로서, 객체가 가비지 수거될 때 메시지를 출력합니다.

WeakKeyDictionary

이제 특별한 종류의 딕셔너리에 대해 이야기해 보겠습니다 – WeakKeyDictionary입니다. 이는 일반 딕셔너리와 비슷하지만, 키가 약한 참조라는 점이 다릅니다!

import weakref

class Attendee:
def __init__(self, name):
self.name = name

party_roles = weakref.WeakKeyDictionary()

alice = Attendee("Alice")
bob = Attendee("Bob")

party_roles[alice] = "DJ"
party_roles[bob] = "Dancer"

print(party_roles[alice])  # 출력: DJ
print(party_roles[bob])    # 출력: Dancer

del alice
print(list(party_roles.keys()))  # 출력: [<__main__.Attendee object at ...>]

이 예제에서, alice를 삭제하면 party_roles 딕셔너리에서 그 항목이 자동으로 제거됩니다. 이는 그녀가 아무도 말하지 않고 파티를 떠나는 것과 같습니다!

WeakValueDictionary

마지막으로, WeakValueDictionary에 대해 이야기해 보겠습니다. 이번에는 값이 약한 참조가 되었습니다, 키가 아니라요.

import weakref

class Party:
def __init__(self, name):
self.name = name

scheduled_parties = weakref.WeakValueDictionary()

summer_bash = Party("Summer Bash")
winter_gala = Party("Winter Gala")

scheduled_parties["June"] = summer_bash
scheduled_parties["December"] = winter_gala

print(scheduled_parties["June"].name)  # 출력: Summer Bash

del summer_bash
print(list(scheduled_parties.keys()))  # 출력: ['December']

여기서, summer_bash를 삭제하면 scheduled_parties 딕셔너리에서 그 항목이 자동으로 사라집니다. 이는 파티가 예약표를 업데이트하지 않고 취소되는 것과 같습니다!

마무리

그리고 여기까지! 우리는 파이썬에서의 약한 참조의 땅을 거쳤습니다. 기본적인 약한 참조에서 콜백 함수, 정리자, 약한 딕셔너리까지, 여러분은 이 강력한 개념에 대한 견고한 기초를 갖추었습니다.

기억하십시오, 약한 참조는 적절한 파티 게스트처럼 – 너무 오래 머물지 않고, 떠나는 시간을 알고 있습니다. 이들은 메모리를 효율적으로 관리하고 순환 참조를 피하는 데 매우 유용합니다.

파이썬 모험을 계속할 때, 이러한 개념들을 마음에 새기십시오. 예상치 못한 순간에 매우 유용하게 사용될 수 있을 것입니다!

메서드/클래스 설명
weakref.ref() 객체에 대한 약한 참조를 생성합니다
weakref.proxy() 약한 참조를 위한 프록시를 생성합니다
weakref.getweakrefcount() 객체에 대한 약한 참조의 수를 반환합니다
weakref.getweakrefs() 객체에 대한 모든 약한 참조의 목록을 반환합니다
weakref.WeakKeyDictionary() 키가 약한 참조인 딕셔너리를 생성합니다
weakref.WeakValueDictionary() 값이 약한 참조인 딕셔너리를 생성합니다
weakref.finalize() 객체가 가비지 수거될 때 호출되는 최종 처리 함수를 등록합니다

코딩이 행복하시고, 파이썬 여정이 흥미로운 발견으로 가득 차길 바랍니다!

Credits: Image by storyset