Python StringIO плохо работает с операторами with

Мне нужно, чтобы заглушка tempfile и StringIO казались идеальными. Только то, что все это терпит неудачу в упущении:

In [1]: from StringIO import StringIO
In [2]: with StringIO("foo") as f: f.read()

--> AttributeError: StringIO instance has no attribute '__exit__'

Каков обычный способ предоставления консервированной информации вместо чтения файлов с недетерминированным содержимым?


person mike3996    schedule 19.08.2012    source источник


Ответы (2)


Модуль StringIO предшествует оператору with. Поскольку StringIO был в любом случае удален в Python 3, вы можете просто использовать его замену, io.BytesIO:

>>> import io
>>> with io.BytesIO(b"foo") as f: f.read()
b'foo'
person phihag    schedule 19.08.2012
comment
Обратите внимание, что модуль io является чистым Python в Python 2.6, тогда как Python 2.7 использует быструю реализацию C Python 3.1. Таким образом, только для Python 2.6 использование io.BytesIO приведет к снижению производительности. - person amcnabb; 11.09.2012
comment
не удалено, из Что нового в Python 3.0: Модули StringIO и cStringIO исчезли. Вместо этого импортируйте модуль io и используйте io.StringIO или io.BytesIO для текста и данных соответственно. - person Bob; 27.08.2017

этот обезьяний патч работает для меня в python2. вызовите monkeypatch в своей процедуре инициализации.

import logging
from StringIO import StringIO
logging.basicConfig(level=logging.DEBUG if __debug__ else logging.INFO)

def debug(*args):
    logging.debug('args: %s', args)
    return args[0]

def monkeypatch():
    '''
    allow StringIO to use `with` statement
    '''
    StringIO.__exit__ = debug
    StringIO.__enter__ = debug

if __name__ == '__main__':
    monkeypatch()
    with StringIO("this is a test") as infile:
        print infile.read()

тестовый забег:

jcomeau@aspire:~/stackoverflow/12028637$ python test.py 
DEBUG:root:args: (<StringIO.StringIO instance at 0xf73e76ec>,)
this is a test
DEBUG:root:args: (<StringIO.StringIO instance at 0xf73e76ec>, None, None, None)
jcomeau@aspire:~/stackoverflow/12028637$
person jcomeau_ictx    schedule 05.09.2016
comment
Обратите внимание, что это работает только для чистой версии python, а не для версии cStringIO, поэтому не поможет заставить быстрый StringIO хорошо играть с with в 2.7. - person welch; 28.01.2017