프로그래밍 언어/Python

Python 객체를 올바르게 정리하는 방법

Rateye 2021. 9. 10. 10:18
728x90
반응형
질문 : Python 객체를 올바르게 정리하려면 어떻게해야합니까?

class Package:
    def __init__(self):
        self.files = []

    # ...

    def __del__(self):
        for file in self.files:
            os.unlink(file)

__del__(self) 는 AttributeError 예외로 실패합니다. __del__() 이 호출 될 때 파이썬이 "전역 변수"(이 컨텍스트의 멤버 데이터?)의 존재를 보장하지 않는다는 것을 이해합니다. 이 경우이고 이것이 예외의 이유 인 경우 객체가 제대로 파괴되는지 어떻게 확인합니까?

답변

정리해야하는 리소스를 관리하기 위해 with 문을 사용하는 것이 좋습니다. 명시 적 close() 문을 사용할 때의 문제는 예외가 발생할 때 리소스 누수를 방지하기 위해 finally 블록에 배치하는 것을 잊어 버릴까 걱정해야한다는 것입니다.

with 문을 사용하려면 다음 메서드를 사용하여 클래스를 만듭니다.

  def __enter__(self)
  def __exit__(self, exc_type, exc_value, traceback)

위의 예에서

class Package:
    def __init__(self):
        self.files = []

    def __enter__(self):
        return self

    # ...

    def __exit__(self, exc_type, exc_value, traceback):
        for file in self.files:
            os.unlink(file)

그런 다음 누군가가 수업을 사용하고 싶을 때 다음을 수행합니다.

with Package() as package_obj:
    # use package_obj

package_obj 변수는 Package 유형의 인스턴스입니다 ( __enter__ 메소드에서 반환 된 값). __exit__ 메소드는 예외 발생 여부에 관계없이 자동으로 호출됩니다.

이 접근 방식을 한 단계 더 발전시킬 수도 있습니다. with 절을 사용하지 않고 생성자를 사용하여 Package를 인스턴스화 할 수 있습니다. 당신은 그런 일이 일어나기를 원하지 않습니다. __enter____exit__ 메서드를 정의하는 PackageResource 클래스를 만들어이 문제를 해결할 수 있습니다. 그런 다음 Package 클래스는 __enter__ 메서드 내에서 엄격하게 정의되어 반환됩니다. with 문을 사용하지 않고는 Package 클래스를 인스턴스화 할 수 없습니다.

class PackageResource:
    def __enter__(self):
        class Package:
            ...
        self.package_obj = Package()
        return self.package_obj

    def __exit__(self, exc_type, exc_value, traceback):
        self.package_obj.cleanup()

다음과 같이 사용합니다.

with PackageResource() as package_obj:
    # use package_obj
출처 : https://stackoverflow.com/questions/865115/how-do-i-correctly-clean-up-a-python-object
728x90
반응형