2012-06-05 5 views
1

순환 참조가 관련되어있을 때 사용자 지정 __del__ 메서드가 실행되지 않는 것처럼 보입니다. 이런 일이 발생하는 이유순환 참조를 포함 할 때 __del__method가 실행되지 않음

class DelClass(): 
     def __init__(self,a): 
      self.prop = a 

     def __del__(self): 
      print 'del' 



if __name__ == "__main__": 

    dc1 = DelClass(None) 
    dc2 = DelClass(dc1)#dc2 referring to dc1 
    dc1.prop = dc2#dc1 referring to dc2, thus creating circular reference 
    del dc1#not executing the custom __del__ method 

    dc = DelClass(1) 
    del dc#executing the custom __del__ method 

: 여기

은 샘플 코드?

편집 : BrenBarn에게 감사드립니다. 이유를 찾았습니다.

import gc 

class DelClass(): 
    def __init__(self,name,a): 
     self.name = name 
     self.prop = a 

    def __del__(self): 
     print '#####deleting',self.name 

dc1 = DelClass("dc1",None) 
dc2 = DelClass("dc2",dc1)#dc2 referring to dc1 
dc1.prop = dc2#dc1 referring to dc2, thus creating circular reference 
print "before deleting dc1,reference count:",len(gc.get_referrers(dc1)) 
del dc1#not executing the custom __del__ method 
print "after deleting dc1, reference count:",len(gc.get_referrers(dc2.prop)) 
print "deleting the reference held by dc2" 
del dc2.prop 
print dc2 

출력은 :

del something은 레퍼런스 카운트가 테스트 코드 여기서 0

도달 할 때

__del__ 만 실행할 1만큼 something의 참조 카운트를 감소 :

before deleting dc1,reference count: 2 
after deleting dc1, reference count: 1 
deleting the reference held by dc2 
#####deleting dc1 
<__main__.DelClass instance at 0x9316dec> 
#####deleting dc2 

또 다른 질문이 나타납니다 :

왜 출력의 마지막 줄 (#####deleting dc2)이 발생합니까?

일부 암시적인 del 작업이 발생합니까?

답변

1

가비지 수집기는 처음 안전하게 삭제할 수있는 정보를 알 수 없기 때문에

3

documentation for __del__for the garbage collector을 읽으십시오. __del__은 아마 당신이 생각하는 것을하지 않으며, del도 아닙니다. __del__은 반드시 del을 호출 할 때 반드시 호출되는 것은 아니며 순환 참조의 경우 호출 될 수 없습니다. 모두 del은 참조 카운트를 1 씩 감소시킵니다.

1

이 내용은 link입니다. 나는 이것이 당신을 도울 것이라고 생각합니다.

del

는 제거합니다에게 로컬 변수를 사용하는 방법으로 __del__

del를 호출하지 않습니다. __del__은 개체가 파괴 될 때 호출됩니다. Python은 언어로서 객체를 파괴 할 때 어떤 보장도하지 않습니다.

---- 업데이트 편집 ----

대답

Some implicit del operation happens?에하면이 link 당신이

파이썬은 __del__ 인 경우에 대한 보증을하지 않습니다 도움이 될 것입니다 읽기 또는 그것이 전혀 불려지는지 여부. 그렇기 때문에 객체가 참조주기의 일부인 경우 __del__ 메서드는 호출되지 않을 것입니다. 왜냐하면주기가 전체적으로 정리 되더라도 파이썬은주기를 중단 할 위치를 결정할 방법이 없기 때문에 __del__ 메소드 (있는 경우)를 호출해야합니다.__del__의 오히려 기발한 의미 때문에 (__del__를 호출하기 위해 객체의 refcount가 일시적으로 증가하고 __del__ 메소드는 다른 곳에 참조를 저장하여 객체의 파괴를 막을 수 있습니다.) 다른 구현에서 일어나는 일은 사마귀. (현재 자이 썬의 정확한 세부 사항은 기억이 나지 않지만 과거에는 몇 번 변경되었다.)

CPython에서 __del__이 호출되면 참조 횟수가 줄어들 자마자 호출된다. (refcount로는 __del__ 방법이라고 유일한 방법이며, 실제 refcount는이 변경 될 때 CPython과는 __del__를 호출하는 유일한 기회이기 때문이다.)는 0

0

이 더 이상 파이썬 3.4 이후로 사실이 아니다. PEP-442을 참조하십시오.