有没有办法浅拷贝现有的文件对象?

时间:2014-10-14 18:08:47

标签: python

这个用例就是基于某个文件对象创建多个生成器,而不会有任何相互篡改的读取状态。

最初我(我认为)有一个使用seek()tell()的工作实现,其中每个生成器都由一个元生成器修饰,该生成器维护文件句柄位置。这在StringIO之类的工作上运行良好,但由于预读缓冲区毁坏了offset,因此在实际文件上失败了。

使用readline()或以其他方式模拟真实的文件对象是不可行的,因为这样做的原因是过大的文件首先提示生成器表达式。因此,丢失预读缓冲区并不是一个很好的选择(顺便说一下,为什么Python首先以这种方式实现?不应该将缓冲区当作缓存而不是实际暴露给用户?正确的封装应该首先阻止这个tell()问题......)

然后我尝试使用copy.copy,但结果如下:<closed file '<uninitialized file>', mode '<uninitialized file>' at 0x7f722ffda810>。哪个似乎无法使用。

是否存在另一种复制方式?有没有办法初始化文件对象?或者我应该完全放弃这个用例,因为它在Python中是不可能的?

1 个答案:

答案 0 :(得分:5)

您正在寻找itertools.tee

from itertools import tee
with open("somefile.txt", "r") as fh:
    fh1, fh2, fh3 = tee(fh, 3)

调用tee后,请勿再次使用父迭代器。但是,tee返回的迭代器可以自由独立地使用。

对于文件对象(保留特定于文件的方法,如read),您可以多次打开文件;每个文件对象在读取文件时都会保留自己的文件指针。

fh1, fh2, fh3 = [open("somefile.txt") for i in range(3)]

或者,如果您已有文件对象fh

fh1, fh2, fh3 = [open(fh.name) for i in range(3)]

这并不能保留已经很高级的文件指针,但它很容易上手:

for x in fh1, fh2, fh3:
    x.seek(fh.tell())