__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__
... или есть третий вариант для достижения этой цели?
1 ответ
Проблема не имеет ничего общего со сборкой мусора. Как документально подтверждено, as
предложение связывает возвращаемое значение __enter__
метод. Вы ничего не возвращаете, поэтому вы получаете None.
Если вы хотите Writer
объект должен быть возвращен, вам нужно сделать return self
в конце __enter__
метод.