Python 为什么';t tempfile.SpooledTemporaryFile是否实现可读、可写、可查找?

Python 为什么';t tempfile.SpooledTemporaryFile是否实现可读、可写、可查找?,python,io,temporary-files,Python,Io,Temporary Files,在Python 3.6.1中,我尝试将tempfile.SpooledTemporaryFile包装到io.TextIOWrapper中: 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(

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

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'
如果我创建这样一个简单的类,我可以绕过这个错误(对于
writeable
seekable
,我会得到类似的错误):


tempfile.SpooledTemporaryFile没有这些属性有什么好的原因吗?

SpooledTemporaryFile
实际上在引擎盖下使用了两种不同的
\u文件实现-最初是一个
io
缓冲区(
StringIO
BytesIO
),直到它滚动并创建一个通过
tempfile.TemporaryFile()
“类文件对象”(例如,当超过
max_size
时)

io.TextIOWrapper
需要一个
BuffereDiabase
基类/接口,该基类/接口由
io.StringIO
io.BytesIO
提供,但不一定由
TemporaryFile()
返回的对象提供(尽管在我对OSX的测试中,
TemporaryFile()提供)
返回了一个
\u io.BufferedRandom
对象,该对象具有所需的接口,我的理论是这可能取决于平台)


因此,我预计您的
MySpooledTempfile
包装器在翻滚后可能会在某些平台上失败。

这很有趣,感谢您的反馈,Mike。看起来posix和非posix(包括cygwin)之间确实存在差异系统。在非posix系统上,
TemporaryFile
实际上是
NamedTemporaryFile
()的别名:当我在Windows系统上测试(
os.name==“nt”
)时,我仍然看到
TemporaryFile()返回的对象
具有
可读
可写
可查找
属性。临时文件/SpooledTemporaryFile似乎只保证类似文件的对象,而该对象可能碰巧也实现了
缓冲数据库
接口……但该标准不保证。(这正是我从阅读代码和文档中得到的,所以希望有更多的知情人士能够澄清这一记录。)关于类似文件的对象的文档显然是模糊的:。可读/可写/可查找的属性是在
IOBase
中的IO流类层次结构的顶部定义的:。另外有趣的是,
TemporaryFile
在mypy中有一个给定类型
IO
。。您是对的,tempfile文档只提到了
file-like对象
,它似乎不能保证读/写之外的任何东西。这似乎是一个bug,因此我已将其作为32600记录在python问题跟踪程序中。从IOBase修补必要属性的解决方法似乎可以使一切正常工作,而且似乎无论对象是否为IO缓冲区,它们都应该存在r实际(临时)文件。
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