Должен ли я делать StringIO.close()?
Некоторые коды:
import cStringIO
def f():
buffer = cStringIO.StringIO()
buffer.write('something')
return buffer.getvalue()
В документации говорится:
StringIO.close()
: освободите буфер памяти. Попытка сделать дальше операции с закрытым объектом StringIO повысят значение ValueError.
Нужно ли делать buffer.close()
, или это произойдет автоматически, когда буфер выходит из области видимости и собирается мусор?
UPDATE:
Я сделал тест:
import StringIO, weakref
def handler(ref):
print 'Buffer died!'
def f():
buffer = StringIO.StringIO()
ref = weakref.ref(buffer, handler)
buffer.write('something')
return buffer.getvalue()
print 'before f()'
f()
print 'after f()'
Результат:
[email protected]:~/projects$ python test.py
before f()
Buffer died!
after f()
[email protected]:~/projects$
Ответы
Ответ 1
Как правило, еще лучше вызвать close()
или использовать оператор with
, поскольку в особых обстоятельствах может возникнуть неожиданное поведение. Например, expat-t22 > , кажется, ожидает, что файл будет закрыт, или он не вернет последний лакомый кусочек анализируемого xml до тех пор, пока не произойдет тайм-аут в некоторых редких случаях.
Но для with
-statement, который обрабатывает закрытие для вас, вы должны использовать класс StringIO
из io
-Modules, как указано в комментарии Ivc.
Это была серьезная головная боль в каком-то унаследованном sax-parser script, который мы решили, закрыв StringIO вручную.
Закрытие "out-of-scope" не работает. Он просто ждал предела ожидания.
Ответ 2
Из источника:
class StringIO:
...
def close(self):
"""Free the memory buffer.
"""
if not self.closed:
self.closed = True
del self.buf, self.pos
So StringIO.close
просто освобождает буфер памяти, удаляя ссылки на StringIO.buf
и StringIO.pos
. Но если self
- сбор мусора, его атрибуты также будут собирать мусор, имеющие тот же эффект, что и StringIO.close
.
Ответ 3
StringIO.close()
- просто удобство для подпрограмм, которые принимают файлоподобные и в конечном итоге пытаются их закрыть. Нет необходимости делать это самостоятельно.
Ответ 4
Я закончил работу с помощью блока try
, чтобы обработать его.
import cStringIO
def f():
buffer = cStringIO.StringIO()
try:
buffer.write('something')
return buffer.getvalue()
finally:
buffer.close()