1

많은 자식 개체를 인스턴스화하는 스크립트가 있습니다. 스크립트 (및 이러한 객체)가 끝나면 객체는 약간의 정리 (특히 임시 파일 닫기 및 삭제)를 수행해야합니다.__del__은 신뢰할 수 없지만 컨텍스트 관리자를 사용하려고하면 개체가 지속되지 않습니다.

어떻게 __del__이 신뢰할 수 없는지 계속 읽습니다.하지만 컨텍스트 관리가 작동하지 않는 것으로 보일 경우 하위 개체는 유지되지 않습니다. 그들은 (파일 읽기 및 쓰기 등의 작업을 수행하기 위해) 배회 할 필요가

예 :

WRITER.PY

import os 

class Writer(object): 
    def __init__(self, filename): 
     self.filename = filename 
     self.open() 

    def open(self): 
     self.fh = open(self.filename, "w+", 0) 

    def write(self, msg): 
     print >>self.fh, str(msg) 

    def close(self): 
     self.fh.close() 
     os.remove(self.filename) 

    def __enter__(self): 
     print "entered" 
#   self.open() 


    def __exit__(self, type, value, traceback): 
     print "__exit__" 
     self.close() 

MAIN.PY

def myfunc(filename): 
    with WRITER.Writer(filename) as writeit: 
     # do some stuff 
     writeit.write("hallo") 
     # do some more stuff 
     writeit.write("more results") 
     # even more stuff 
     writeit.write("goodbye") 

하지만 실행 myfunc()이면 개체는 __init__()을 마치 자마자 가비지 수집됩니다. 그것은 입력에서 종료로 직행하고 with 문 다음에 아무 의무도 수행하지 않습니다. __init__ 또는 __enter__에 공개 입력하면 문제가되지 않습니다.

출력 :

Traceback (most recent call last): 
    File "/shared/GitHub/Tesera/MRAT_Refactor/bin/MAIN.py", line 13, in <module> 
    myfunc("./tempfile") 
    File "/shared/GitHub/Tesera/MRAT_Refactor/bin/MAIN.py", line 6, in myfunc 
    writeit.write("hallo") 
AttributeError: 'NoneType' object has no attribute 'write' 
entered 
__exit__    

이런 식으로 상황에 맞는 관리자를 사용하는 방법은, __del__를 사용하는 더 좋은 방법이 있나요 ... 또는 이러한 목표를 달성하기 위해 세 번째 옵션이있다?

+0

편집 해 주셔서 감사합니다. 내 시간은 오전 2시 였고 그 태그를 알아낼 수 없었습니다 :-) – RightmireM

답변

8

문제는 가비지 수집과 관련이 없습니다. documented으로 as 절은 __enter__ 메서드의 반환 값을 바인딩합니다. 아무것도 돌려주지 않으므로 아무 것도 얻지 못합니다.

Writer 개체를 반환하려면 __enter__ 메서드 끝에 return self을 수행해야합니다.

+0

설명해 주셔서 감사합니다! 나는 그 문서를 훑어 보았고 그면을 파악하지 못했습니다. – RightmireM