为什么tempfile.SpooledTemporaryFile不能实现可读,可写,可搜索?

时间:2017-11-07 14:21:27

标签: python io temporary-files

在Python 3.6.1中,我尝试在io.TextIOWrapper中包装tempfile.SpooledTemporaryFile:

with tempfile.SpooledTemporaryFile() as tfh:
    do_some_download(tfh)
    tfh.seek(0)
    wrapper = io.TextIOWrapper(tfh, encoding='utf-8')
    yield from do_some_text_formatting(wrapper)

wrapper = io.TextIOWrapper(tfh, encoding='utf-8')行给出了一个错误:

AttributeError: 'SpooledTemporaryFile' object has no attribute 'readable'

如果我创建一个这样的简单类,我可以绕过错误(我得到writableseekable的类似错误):

class MySpooledTempfile(tempfile.SpooledTemporaryFile):                                                                                
    @property                                                                                                                          
    def readable(self):                                                                                                                
        return self._file.readable                                                                                                     

    @property                                                                                                                          
    def writable(self):                                                                                                                
        return self._file.writable                                                                                                     

    @property                                                                                                                          
    def seekable(self):                                                                                                                
        return self._file.seekable 

为什么tempfile.SpooledTemporaryFile还没有这些属性?

1 个答案:

答案 0 :(得分:4)

SpooledTemporaryFile实际上使用了2个不同的_file实现 - 最初是io缓冲区(StringIOBytesIO),直到它翻转并创建通过tempfile.TemporaryFile()创建“类文件对象”(例如,超过max_size时)。

io.TextIOWrapper需要BufferedIOBase基类/接口,由io.StringIOio.BytesIO提供,但不一定由TemporaryFile()返回的对象提供(虽然在我对OSX的测试中,TemporaryFile()返回了一个_io.BufferedRandom对象,它具有所需的接口,我的理论可能取决于平台)。

所以,我希望你的MySpooledTempfile包装器在翻转后在某些平台上可能会失败。