在Python中存储字符串的对象
class MyWriter:
def __init__(self, stdout):
self.stdout = stdout
self.dumps = []
def write(self, text):
self.stdout.write(smart_unicode(text).encode('cp1251'))
self.dumps.append(text)
def close(self):
self.stdout.close()
writer = MyWriter(sys.stdout)
save = sys.stdout
sys.stdout = writer
我用 self.dumps
这个列表来存储从打印中得到的数据。有没有更方便的方式来把字符串行存储在内存里呢?理想情况下,我想把它们合成一个大字符串。我可以用上面的代码 "\n".join(self.dumps)
来做到这一点。也许直接把字符串拼接在一起会更好,比如 self.dumps += text
?
2 个回答
我很确定,使用 '\n'.join(self.dumps)
会比 self.dumps += text
快得多。
解释:在Python中,字符串是不可变的,这意味着如果你把两个字符串拼接在一起,就会生成一个新的字符串,并把原来的两个字符串复制到这个新字符串里。如果你只做一次,这没什么问题,但如果在一个循环里这样做,每次循环都会复制整个文本。另一方面,join()
是一个用C语言写的内置函数,它能有效地重新分配内存并改变字符串的结尾。所以,它应该会快很多。
所以,你的代码完全没问题。干得好!
附注:缺少了 flush() 函数。
要把一堆字符串合成一个字符串,用 ''.join
是个不错的方法。不过,如果你想要更直接的解决办法:
import cStringIO
class MyWriter(object):
def __init__(self, stdout):
self.stdout = stdout
self.dumps = cStringIO.StringIO()
self.final = None
def write(self, text):
self.stdout.write(smart_unicode(text).encode('cp1251'))
self.dumps.write(text)
def close(self):
self.stdout.close()
self.final = self.dumps.getvalue()
self.dumps.close()
def getvalue(self):
if self.final is not None:
return self.final
return self.dumps.getvalue()
getvalue
这个方法在字符串输入输出对象(string-io)关闭后是不能调用的,因为关闭对象会让它丢掉自己的缓存内存。所以我在关闭之前就把 self.final
设定好了。除了 getvalue
,字符串输入输出对象基本上是一个很好的“像文件一样的对象”的实现,所以当你想把原本设计用来 print
输出结果的代码改成把结果保存在内存中时,它就特别有用了;而且这也是一个很好的方法来“逐步构建一个字符串”——只需要用 write
写入每一部分,完成后(或者在任何时候)用 getvalue
查看你到目前为止构建的内容。
现代 Python 的风格通常是更倾向于低抽象的方法(明确地构建一个字符串列表,然后在需要的时候把它们合成一个字符串),但使用稍微高抽象的“字符串输入输出”方法也没有问题。
(还有一种方法似乎不太流行,就是不断地用 extend
来扩展一个 array.array
的字符数组,只是为了全面列出这些方法;-)