当前位置: 首页 > 面试题库 >

如何清除弦乐对象?

公冶渝
2023-03-14
问题内容

我创建了一个stringio对象,并且其中包含一些文本。我想清除其现有值并重用它,而不是调用它。反正有这样做吗?


问题答案:

不必费心清除它,只需创建一个新的文件-更快。

方法

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()
'\x00\x00\x00bar'

因此,在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

因此,忽略潜在的内存问题(del oldstringio),截断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而不是截断和寻找。



 类似资料:
  • Swift 4中的字符串是一个有序的字符集合,例如“Hello,World!”。 它们由Swift 4数据类型String表示,后者又表示Character类型值的集合。 创建一个字符串 您可以使用字符串文字或创建String类的实例来创建String,如下所示 - // String creation using String literal var stringA = "Hello, Swif

  • 问题内容: 以下语句之间有什么区别 尽管类是class,但是为什么我们需要创建一个字符串“ CONSTANT”变量作为最终变量? 问题答案: 在这种情况下,该变量只能分配一次。再次为其分配不同的对象会导致编译错误。 我认为,造成混淆的原因是该关键字可以在几种不同的上下文中使用: final class:该类不能被子类化。 最终方法:该方法不能被覆盖。 最终变量:该变量只能分配一次。 有关每种情况的

  • 当Kubernetes pod进入状态时,您将修复底层问题。你怎么强迫它重新安排?

  • 我已经在运行的Java应用程序上运行了命令,下面是我得到的信息: 看来68MB的permgen中有大约89MB的内部字符串。是否存在未存储在permgen中的内部字符串?

  • 问题内容: 我在Swift 2中使用SFSafariViewController在具有ios 9.1(13B143)的iPad Air 2上显示网页。每个网页都需要用户提供凭据。但是,当用户按下注销按钮时,我需要清除这些凭据。我尝试使用以下方法: 但这不起作用。实际上,“ DELETING CREDENTIAL”和“ DELETING COOKIE”从未打印过。此外,我可以从iPad上完全删除该应

  • 问题内容: 在导入flask时,我们导入模块等。 是一种字典,可以使用会话进行访问。 现在,我尝试清除尝试构建网站时使用的所有垃圾变量。 关于stackoverflow的答案之一使用了类似清除会话内容的命令。但是,这样的命令会产生错误,表明不存在这样的命令。 谁能为我指出每次关闭服务器或关闭网站时如何清除和如何清除会话? 问题答案: 我将这样的会话与flask一起使用,它确实起作用。我虽然不使用,