programing

__del__ 메서드는 무엇이며 어떻게 호출합니까?

nasanasas 2020. 9. 13. 10:41
반응형

__del__ 메서드는 무엇이며 어떻게 호출합니까?


코드를 읽고 있습니다. __del__메소드가 정의 된 클래스가 있습니다 . 이 메서드가 클래스의 인스턴스를 파괴하는 데 사용된다는 것을 알아 냈습니다. 그러나이 방법이 사용되는 곳을 찾을 수 없습니다. 그 주된 이유는이 방법이 어떻게 사용되는지 모르기 때문입니다 obj1.del(). 그래서, 내 질문은 __del__메서드 를 호출하는 방법입니다.


__del__A는 파이널 라이저는 . 객체에 대한 모든 참조가 삭제 된 후 어느 시점에서 발생 하는 객체가 가비지 수집 될 때 호출 됩니다.

A의 간단한 경우 이것은 당신이 말하는 직후가 될 수 del x있는 경우, 또는 x함수 종료 후, 지역 변수입니다. 특히 순환 참조가없는 한 CPython (표준 Python 구현)은 즉시 가비지 수집합니다.

그러나 이것은 CPython 구현 세부 사항 입니다. Python 가비지 컬렉션 의 유일한 필수 속성은 모든 참조가 삭제 된 후에 발생한다는 것입니다 . 따라서 이는 즉시 발생하지 않을 수도 있고 전혀 발생하지 않을 수도 있습니다 .

더욱, 변수에 대해 오랫동안 살 수 많은 이유 , 예를 들면 전파 예외 나 또한 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  

더 정확한 질문이지만 다른 질문에 대한 답변을 작성했습니다.

생성자와 소멸자는 어떻게 작동합니까?

여기에 약간의 의견이있는 답변이 있습니다.

사용하지 마십시오 __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__기능이 마음에 들지 않는 비정상적인 이유 .

  • 누군가가 __del__그것을 가져올 때마다 30 개의 혼란 메시지로 이어집니다.
  • Zen of Python에서 다음 항목을 중단합니다.
    • 단순한 것이 복잡한 것보다 낫습니다.
    • 특별한 경우는 규칙을 어길만큼 특별하지 않습니다.
    • 오류는 조용히 전달되지 않아야합니다.
    • 모호함에도 불구하고 추측하려는 유혹을 거부하십시오.
    • 이를 수행하는 확실한 방법은 하나, 그리고 바람직하게는 하나만 있어야합니다.
    • 구현이 설명하기 어렵다면 그것은 나쁜 생각입니다.

따라서 사용하지 않는 이유를 찾으십시오 __del__.


__del__객체가 쓰레기 수집 때 방법, 그것은 호출됩니다. 하지만 반드시 호출이 보장되는 것은 아닙니다. 다음 코드는 그 자체로이를 수행 할 필요는 없습니다.

del obj

그 이유 del는 참조 횟수를 1만큼 감소시키기 때문 입니다. 다른 것이 객체에 대한 참조를 가지고 있으면 __del__호출되지 않습니다.

__del__하지만 사용에 대한 몇 가지주의 사항이 있습니다 . 일반적으로 그들은 일반적으로 그다지 유용하지 않습니다. close 메소드 또는 with 문 을 사용하고 싶은 것처럼 들립니다 .

메소드 __del__ 대한 파이썬 문서를 참조하십시오 .

One other thing to note: __del__ methods can inhibit garbage collection if overused. In particular, a circular reference that has more than one object with a __del__ method won't get garbage collected. This is because the garbage collector doesn't know which one to call first. See the documentation on the gc module for more info.


The __del__ method (note spelling!) is called when your object is finally destroyed. Technically speaking (in cPython) that is when there are no more references to your object, ie when it goes out of scope.

If you want to delete your object and thus call the __del__ method use

del obj1

which will delete the object (provided there weren't any other references to it).

I suggest you write a small class like this

class T:
    def __del__(self):
        print "deleted"

And investigate in the python interpreter, eg

>>> 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
>>>   

Note that jython and ironpython have different rules as to exactly when the object is deleted and __del__ is called. It isn't considered good practice to use __del__ though because of this and the fact that the object and its environment may be in an unknown state when it is called. It isn't absolutely guaranteed __del__ will be called either - the interpreter can exit in various ways without deleteting all objects.


As mentioned earlier, the __del__ functionality is somewhat unreliable. In cases where it might seem useful, consider using the __enter__ and __exit__ methods instead. This will give a behaviour similar to the with open() as f: pass syntax used for accessing files. __enter__ is automatically called when entering the scope of with, while __exit__ is automatically called when exiting it. See this question for more details.

참고URL : https://stackoverflow.com/questions/1481488/what-is-the-del-method-how-to-call-it

반응형