15

Django docs는 주제에 이런 말 : 당신의 핸들러가 로컬 기능이있는 경우, 가비지 수집 될 수 있도록Django의 시그널 처리가 기본적으로 콜백에 약한 참조를 사용하는 이유는 무엇입니까?

참고 또한 장고 저장, 기본적으로 약한 참조로 핸들러를 신호 것을. 이 문제를 방지하려면 신호의 connect()를 호출하면 weak = False를 전달합니다.

이것이 왜 기본값인지에 대한 설명을 찾을 수 없었으며 암시 적으로 사라지도록 명시 적으로 등록한 신호를 왜 원하는지 이해할 수 없습니다. 그렇다면 약한 참조의 유스 케이스는 무엇입니까? 그리고 왜 이것이 기본입니까?

99 %의 경우에는 아무런 문제가 없을 것입니다. 그러나 여기에 이해할 수없는 것이 있습니다. 언젠가는 나를 물어 뜯을 수있는 "잡기 (gotchas)"가 있는지 알고 싶습니다.

답변

8

신호 핸들러는 약 신호가 여전히 날아가고 있기 때문에 신호 처리기를 명시 적으로 삭제 한 후 가비지 수집되지 않도록 참조하는 객체가 약한 참조로 저장됩니다.

+0

물론 신호 처리기가 명시 적으로 연결이 끊어지면 신호 처리기가 어디에서나 참조되지 않고 그 중 아무 것도 가비지 수집을 방해하지 않습니다. 케이스. 약한 참조를 사용하면 신호가 명시 적으로 연결 해제되지 않은 경우에만 차이가 발생하는 것처럼 보이고 요청하지 않으면 신호가 끊어지기를 원하는 이유가 무엇입니까? –

+0

맞습니다. 신호 처리기가 가비지 수집되도록 약한 참조가 없으면 신호 처리기를 삭제하고 신호를 연결 해제해야합니다. 이것은 모든 사람에게 명백하지 않을 수 있으므로, 이것이 약한 참조가 기본적으로 사용되는 이유라고 생각합니다. –

+1

매우 밀도가 높아서 미안하지만 이해가 안됩니다. 나는 당신이 신호를 "연결 해제"한다는 것을 이해하고 있다고 생각한다. 핸들러를 인자로 전달하여'Signal' 인스턴스에서'disconnect' 메소드를 호출하십시오. 하지만 신호 처리기를 "삭제"한다는 것은 무엇을 의미합니까? –

4

바운드 메서드는 속한 개체에 대한 참조를 유지합니다. 그렇지 않으면 self을 채울 수 없습니다 (참조 : Python documentation). 다음 코드를 고려하십시오

import gc 
class SomeLargeObject(object): 
    def on_foo(self): pass 

slo = SomeLargeObject() 
callbacks = [slo.on_foo] 

print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)] 
del slo 
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)] 
callbacks = [] 
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)] 

출력 : 콜백에 weakrefs을 유지하는 경우

[<__main__.SomeLargeObject object at 0x15001d0>] 
[<__main__.SomeLargeObject object at 0x15001d0>] 
[] 

하나 개 중요한 것은 알고 그들은 항상 즉석에서 만들어지기 때문에 당신이 직접 결합 방법을 weakref 수 없다는 것입니다 :

>>> class SomeLargeObject(object): 
... def on_foo(self): pass 
>>> import weakref 
>>> def report(o): 
... print "about to collect" 
>>> slo = SomeLargeObject() 
>>> #second argument: function that is called when weakref'ed object is finalized 
>>> weakref.proxy(slo.on_foo, report) 
about to collect 
<weakproxy at 0x7f9abd3be208 to NoneType at 0x72ecc0> 
+0

나는 장고 구현을 감추고 있었고 실제로 바인딩 된 메서드에 약한 참조를 제공하기위한 특별한 노력이 있음을 알았습니다. 그러나 언 바운드 메서드는 어떨까요? 그들에 대한 언급은 어디에 보관됩니까?가비지 콜렉션을 트리거하는 것은 무엇입니까? 언제 그들이 정의 된 모듈을 델? – hsribei