Должен ли я делать StringIO.close ()? - PullRequest
27 голосов
/ 15 марта 2012

Код:

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()'

Результат:

vic@wic:~/projects$ python test.py 
before f()
Buffer died!
after f()
vic@wic:~/projects$

Ответы [ 4 ]

14 голосов
/ 15 марта 2012

Как правило, все же лучше вызывать close() или использовать оператор with, потому что в особых обстоятельствах может произойти неожиданное поведение. Например, expat- IncrementalParser, похоже, ожидает, что файл будет закрыт, или он не вернет последний кусочек проанализированного xml, пока в некоторых редких случаях не произойдет тайм-аут.

Но для with -стата, который обрабатывает закрытие для вас, вы должны использовать класс StringIO из io -модулей, как указано в комментарии Ivc.

Это было большой головной болью в некоторых старых скриптах сакс-парсера, которые мы решили, закрыв StringIO вручную.

Закрытие "вне области" не сработало. Он просто ждал ограничения времени ожидания.

11 голосов
/ 23 августа 2013

Из источника:

class StringIO:
    ...
    def close(self):
        """Free the memory buffer.
        """
        if not self.closed:
            self.closed = True
            del self.buf, self.pos

Так что StringIO.close просто освобождает буфер памяти, удаляя ссылки на StringIO.buf и StringIO.pos. Но если self является сборщиком мусора, его атрибуты также будут сборщиками мусора, что будет иметь тот же эффект, что и StringIO.close.

.
8 голосов
/ 15 марта 2012

StringIO.close() - это просто удобство для подпрограмм, которые принимают файлоподобные и в конечном итоге пытаются их закрыть. Нет необходимости делать это самостоятельно.

3 голосов
/ 08 апреля 2014

Я завелся с помощью блока try, чтобы справиться с этим.

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    try:
        buffer.write('something')
        return buffer.getvalue()
    finally:
        buffer.close()
...