답변:
__del__
A는 파이널 라이저는 . 객체에 대한 모든 참조가 삭제 된 후 어느 시점에서 발생 하는 객체가 가비지 수집 될 때 호출 됩니다.
A의 간단한 경우 이것은 당신이 말하는 직후가 될 수 del x
있는 경우, 또는 x
함수 종료 후, 지역 변수입니다. 특히 순환 참조가없는 한 CPython (표준 Python 구현)은 즉시 가비지 수집합니다.
그러나 이것은 CPython 의 구현 세부 사항 입니다. 유일한 요구 파이썬 가비지 컬렉션의 속성은 그런 일이 있다는 것입니다 후 모든 참조가 삭제 된 필요하지 않습니다이 힘이 발생하므로 직후 와 전혀 발생하지 않을 수 있습니다 .
더욱, 변수에 대해 오랫동안 살 수 많은 이유 , 예를 들면 전파 예외 나 또한 0보다 변수 참조 카운트 이상을 유지할 수 있습니다 모듈 성찰은, 변수의 일부가 될 수 있습니다 참조주기 - CPython의 쓰레기 수거와 휴식 대부분 켜져 , 전부는 아니지만 그러한주기는 물론 주기적으로 만 발생합니다.
실행을 보장 할 수 없기 때문에 실행 해야하는 코드를 입력 해서는 안됩니다.__del__()
대신이 코드는 블록의 finally
절이나 명령문 try
의 컨텍스트 관리자에 속합니다 with
. 그러나 다음과 같은 유효한 사용 사례 가 있습니다 __del__
. 예를 들어 객체가 X
참조 Y
사본을 Y
전역 cache
( cache['X -> Y'] = Y
) 에 참조하고 보관하는 X.__del__
경우 캐시 항목도 삭제하는 것이 정중합니다 .
소멸자가 (위의 지침을 위반하여) 필요한 정리를 제공한다는 것을 알고 있다면 , 메서드로서 특별한 것이 없기 때문에 직접 호출 할 수 있습니다 : x.__del__()
. 분명히 두 번 전화해도 괜찮다는 것을 알고있는 경우에만 그렇게해야합니다. 또는 최후의 수단으로 다음을 사용하여이 방법을 재정의 할 수 있습니다.
type(x).__del__ = my_safe_cleanup_method
__exit__
이런 맥락에서? 이후 또는 이전 __del__
또는 함께 실행 됩니까?
__del__
메서드는 프로그램 종료시에도 실행되지 않을 수 있으며, 종료시 실행하더라도 __del__
인터프리터가 바쁘게 작동하는 동안에도 제대로 작동 하는 메서드를 작성 하려면 많은 프로그래머가 적용하는 것보다 더 신중한 코딩이 필요합니다. (CPython 정리는 일반적으로 __del__
인터프리터 종료시 실행할 메서드를 가져 오지만 여전히 충분하지 않은 경우가 있습니다. 데몬 스레드, C 수준 전역 및 __del__
다른에서 생성 된 개체 __del__
는 모두 __del__
메서드가 실행되지 않는 원인이 될 수 있습니다 .)
더 정확한 질문이지만 다른 질문에 대한 답변을 작성했습니다.
여기에 약간의 의견이있는 답변이 있습니다.
사용하지 마십시오 __del__
. 이것은 C ++ 또는 소멸자를 위해 만들어진 언어가 아닙니다. 이 __del__
메서드는 실제로 Python 3.x에서 사라져야하지만 누군가 의미있는 사용 사례를 찾을 수있을 것이라고 확신합니다. 을 사용해야하는 경우 http://docs.python.org/reference/datamodel.html__del__
의 기본 제한 사항에 유의 하세요.
__del__
가비지 수집기가 객체를 수집 할 때 호출됩니다. 객체에 대한 마지막 참조를 잃었을 때가 아니라 del object
.__del__
__del__
MRO (메서드 확인 순서)인지 아니면 각 슈퍼 클래스 만 호출하는지는 확실하지 않지만 수퍼 클래스에서 임의의 호출을 담당합니다 .__del__
가비지 수집기가 검출하고, 링크리스트에 마지막 참조 손실 같은 환상 링크 청소 포기한다는 수단. gc.garbage에서 무시 된 객체 목록을 가져올 수 있습니다. 때때로 약한 참조를 사용하여 순환을 완전히 피할 수 있습니다. 이것은 때때로 논쟁이되고 있습니다 : http://mail.python.org/pipermail/python-ideas/2009-October/006194.html 참조 .__del__
함수는 속이고, 객체에 대한 참조를 저장하고, 가비지 수집을 중지 할 수 있습니다.__del__
는 무시됩니다.__del__
보완 __new__
보다 훨씬 더 __init__
. 이것은 혼란스러워집니다. 설명 및 문제는 http://www.algorithm.co.il/blogs/programming/python-gotchas-1- del -is-not-the-opposite-of- init / 를 참조 하십시오 .__del__
파이썬에서 "잘 사랑받는"아이가 아닙니다. sys.exit () 문서는 나가기 전에 가비지 수집 여부를 지정하지 않으며 많은 이상한 문제가 있음을 알 수 있습니다. __del__
on globals를 호출 하면 이상한 순서 문제가 발생합니다 (예 : http://bugs.python.org/issue5099) . 실패 __del__
하더라도 호출 해야합니까 __init__
? 긴 스레드에 대해서는 http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423 을 참조 하십시오 .그러나 다른 한편으로는:
__del__
close 문을 호출하는 것을 잊지 않음을 의미합니다. 전문가의 관점 은 http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python/ 을 참조하십시오 __del__
. 이것은 일반적으로 ctypes 또는 기타 특수 리소스를 해제하는 것입니다.그리고 그 __del__
기능이 마음에 들지 않는 비정상적인 이유 .
__del__
그것을 가져올 때마다 30 개의 혼란 메시지로 이어집니다.따라서 사용하지 않는 이유를 찾으십시오 __del__
.
__del__
하지만 어떻게 호출해야하는지에 __del__
대한 귀하의 대답은 흥미 롭습니다.
__del__
객체가 쓰레기 수집 때 방법, 그것은 호출됩니다. 하지만 반드시 호출이 보장되는 것은 아닙니다. 다음 코드는 그 자체로이를 수행 할 필요는 없습니다.
del obj
그 이유 del
는 참조 횟수를 1만큼 감소시키기 때문 입니다. 다른 것이 객체에 대한 참조를 가지고 있으면 __del__
호출되지 않습니다.
__del__
하지만 사용에 대한 몇 가지주의 사항이 있습니다 . 일반적으로 그들은 일반적으로 그다지 유용하지 않습니다. close 메소드 또는 with 문 을 사용하고 싶은 것처럼 들립니다 .
메소드 에__del__
대한 파이썬 문서를 참조하십시오 .
주의해야 할 또 다른 사항 : __del__
메소드가 과도하게 사용되면 가비지 수집을 금지 할 수 있습니다. 특히 __del__
메서드가 있는 개체가 두 개 이상있는 순환 참조는 가비지 수집되지 않습니다. 가비지 수집기가 먼저 호출 할 항목을 알지 못하기 때문입니다. 자세한 정보 는 gc 모듈에 대한 문서를 참조하십시오 .
이 __del__
메서드 (맞춤법에주의하세요!)는 객체가 마침내 파괴 될 때 호출됩니다. 기술적으로 말하면 (cPython에서) 객체에 대한 참조가 더 이상 없을 때, 즉 범위를 벗어날 때입니다.
객체를 삭제하고 __del__
메서드 를 호출 하려면
del obj1
객체를 삭제합니다 (다른 참조가없는 경우).
이런 작은 수업을 작성하는 것이 좋습니다
class T:
def __del__(self):
print "deleted"
그리고 파이썬 인터프리터에서 조사하십시오.
>>> a = T()
>>> del a
deleted
>>> a = T()
>>> b = a
>>> del b
>>> del a
deleted
>>> def fn():
... a = T()
... print "exiting fn"
...
>>> fn()
exiting fn
deleted
>>>
jython과 ironpython은 객체가 정확히 언제 삭제되고 __del__
호출 되는지에 대한 규칙이 다릅니다 . __del__
이것과 객체와 그 환경이 호출 될 때 알 수없는 상태에있을 수 있다는 사실 때문에 사용하는 것은 좋은 습관으로 간주되지 않습니다 . 절대적 __del__
으로 호출 될 것이라는 보장은 없습니다 . 인터프리터는 모든 객체를 삭제하지 않고 다양한 방법으로 종료 할 수 있습니다.
use del obj1
나쁜 아이디어에 의존하는 것 같다.