TL; DR
不必费心清除它,只需创建一个新的文件-更快。
方法
Python 2
这是我将如何发现此类情况的方法:
>>> from StringIO import StringIO>>> dir(StringIO)['__doc__', '__init__', '__iter__', '__module__', 'close', 'flush', 'getvalue', 'isatty', 'next', 'read', 'readline', 'readlines', 'seek', 'tell', 'truncate', 'write', 'writelines']>>> help(StringIO.truncate)Help on method truncate in module StringIO:truncate(self, size=None) unbound StringIO.StringIO method Truncate the file's size. If the optional size argument is present, the file is truncated to (at most) that size. The size defaults to the current position. The current file position is not changed unless the position is beyond the new file size. If the specified size exceeds the file's current size, the file remains unchanged.
所以,你想要
.truncate(0)。但是初始化一个新的StringIO可能更便宜(更容易)。请参阅下面的基准。
Python 3
>>> from io import StringIO>>> dir(StringIO)['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'getvalue', 'isatty', 'line_buffering', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines']>>> help(StringIO.truncate)Help on method_descriptor:truncate(...) Truncate size to pos. The pos argument defaults to the current file position, as returned by tell(). The current file position is unchanged. Returns the new absolute position.
重要的是要注意,现在 文件的当前位置保持不变 ,而将其截断为零将重置Python 2变体中的位置。
因此,对于Python 2,您只需要
>>> from cStringIO import StringIO>>> s = StringIO()>>> s.write('foo')>>> s.getvalue()'foo'>>> s.truncate(0)>>> s.getvalue()''>>> s.write('bar')>>> s.getvalue()'bar'如果在Python 3中执行此操作,则不会获得预期的结果:
>>> from io import StringIO>>> s = StringIO()>>> s.write('foo')3>>> s.getvalue()'foo'>>> s.truncate(0)0>>> s.getvalue()''>>> s.write('bar')3>>> s.getvalue()'x00x00x00bar'因此,在Python 3中,您还需要重置位置:
>>> from cStringIO import StringIO>>> s = StringIO()>>> s.write('foo')3>>> s.getvalue()'foo'>>> s.truncate(0)0>>> s.seek(0)0>>> s.getvalue()''>>> s.write('bar')3>>> s.getvalue()'bar'如果
truncate在Python
2代码中使用该方法,则
seek(0)在同一时间调用(在此之前或之后都没关系)是更安全的,这样,当您不可避免地将其移植到Python
3时,代码就不会中断。这还有另一个原因您应该只创建一个新
StringIO对象!
时报
Python 2
>>> from timeit import timeit>>> def truncate(sio):... sio.truncate(0)... return sio... >>> def new(sio):... return StringIO()...
当为空时,使用StringIO:
>>> from StringIO import StringIO>>> timeit(lambda: truncate(StringIO()))3.5194039344787598>>> timeit(lambda: new(StringIO()))3.6533868312835693
使用StringIO导入3KB数据:
>>> timeit(lambda: truncate(StringIO('abc' * 1000)))4.3437709808349609>>> timeit(lambda: new(StringIO('abc' * 1000)))4.7179079055786133与cStringIO相同:
>>> from cStringIO import StringIO>>> timeit(lambda: truncate(StringIO()))0.55461597442626953>>> timeit(lambda: new(StringIO()))0.51241087913513184>>> timeit(lambda: truncate(StringIO('abc' * 1000)))1.0958449840545654>>> timeit(lambda: new(StringIO('abc' * 1000)))0.98760509490966797因此,忽略潜在的内存问题(
deloldstringio),截断a的速度更快
StringIO.StringIO(空的速度快3%,3KB数据的速度快8%),但是创建新的
cStringIO.StringIO(快空的速度快8%,
3KB数据快10%)。因此,我建议仅使用最简单的一种-假设您正在使用CPython,请使用
cStringIO并创建新的。
Python 3
相同的代码,只是
seek(0)放入。
>>> def truncate(sio):... sio.truncate(0)... sio.seek(0)... return sio... >>> def new(sio):... return StringIO()...
空时:
>>> from io import StringIO>>> timeit(lambda: truncate(StringIO()))0.9706327870007954>>> timeit(lambda: new(StringIO()))0.8734330690022034
在3KB数据中:
>>> timeit(lambda: truncate(StringIO('abc' * 1000)))3.5271066290006274>>> timeit(lambda: new(StringIO('abc' * 1000)))3.3496507499985455因此,对于Python
3,创建一个新的而不是重复使用一个空白的速度快11%,而创建一个新的而不是重复使用3K的速度快5%。同样,创建一个新的
StringIO而不是截断和寻找。



