2011-11-20 3 views
5
class ToBeDeleted: 
    def __init__(self, value): 
     self.value = val 

    # Whatever... 

    def __del__(self): 
     print self.value 

l = [ToBeDeleted(i) for i in range(3)] 
del l 

이 문자는 2, 1, 0입니다. 이제목록에 'del'이 표시됩니다.


  • , 삭제 된 요소의 순서는 사양 어딘가에 정의 또는은 구현이다? (또는 어쩌면 내가 이해하지 못하는 기본 역학)

  • 출력, 예를 들어, 0, 1, 2 수 있을까? 2, 1, 0 주문은 삭제하는 동안 요소에 대한 메모리 재 할당을 피하기 위해 수행되었지만 여전히 질문이 남아 있습니다.

  • 그리고 마지막 하나 - del ldel l[:] 문장의 차이점은 무엇입니까?

+3

아주 많이 의심의 여지 있음. 특정 주문에 의존하는 코드를 작성하려고 생각하지 마십시오. –

+0

순서가 지정되었다고해도, 어디에서나 목록 요소에 대한 참조를 보유 할 수 있으므로 '__del__' 메서드가 호출되는 순서는 목록에서 참조가 제거되는 순서와 다를 수 있습니다. – millimoose

답변

8

기호 리터 사라 할 수 있도록 목록에 대한 참조를 제거합니다 del l을 실행합니다. 반대로 del l[:]을 실행하면 목록의 내용이 제거되고 l은 빈 목록으로 남습니다.

__del__ 메서드는 인스턴스에 대한 마지막 참조가 삭제 될 때 실행되는 메서드입니다.

삭제 순서는 지정되지 않았으며 구현에 따라 다릅니다. del l을 실행할 때 목록의 참조 카운트가 l이고 해당 요소가 하나씩 감소합니다.

pypy으로 가비지 수집기가 실행될 때까지는 아무런 변화가 없습니다. 개체 제거의 순서는 GC가 개체를 방문하는 순서에 따라 다릅니다.

cpython에서 오른쪽에서 왼쪽으로 참조 감소가 발생한다는 점을 관찰 할 때 OP가 정확합니다. del l[:]을 호출 할 때 refcount를 감소시키는 데 사용되는 코드는 http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l700입니다. del l를 호출하면, 비슷한 코드가 refcount를을 감소하는 데 사용됩니다 http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l596

+1

고맙습니다. 그러나 삭제 된 요소의 순서는 어떻습니까? –

1
  • 삭제 순서는 구현 고유의 것입니다.
  • 첫 번째 요점에 대한 답변에 따르면 예를 들어 다른 순서 (요소도 첫 번째, 임의의, 무엇이든)로 삭제할 수 있으며 재 할당을 피하는 것이 거의 관련이 없습니다. 구현이 어린이를 걷는 방법에 관한 문제 일뿐입니다. 아마도 메모리 할당자는 해제 순서에 따라 할당 순서가 바뀌면 더 행복 할 것입니다. 그러나 그것은 단지 추측입니다.
  • del l은 변수 자체를 지우지 만 그 밖의 것이 없다면 목록을 지우는 반면, del l[:]은 목록에서 모든 요소를 ​​제거합니다. 시도 del l; print l.
2

기타 답변은 이미 있습니다. CPython 소스에서 찾은 것을 추가 할 것입니다.

listobject.c 파일의 list_dealloc 기능은 즉시 참조 카운트를 감소시킬 목록 항목 전체를 반복하기 전에이 댓글이 포함되어`__del의 __() 호출의 순서가`어디서든 지정

/* Do it backwards, for Christian Tismer. 
     There's a simple test case where somehow this reduces 
     thrashing when a *very* large list is created and 
     immediately deleted. */ 
+0

그레이트 찾으십시오! 이것은 삭제 순서가 지정되지 않았거나 절대 존재하지 않을 수도 있다는 상당히 강력한 증거입니다. – millimoose

관련 문제