打开&写入一个类似文件的对象,但避免AttributeError关于缺少open()



我想有一个函数,可以写入内容到一个类似文件的对象。它接受pathlib.Path对象或io.StringIO对象。第一个需要先进行open()处理,第二个不需要。

因此,在我看来,我必须显式地检查对象的类型,以知道我是否必须在它上调用open()

是否有一个优雅和python的方法来解决这个问题?

这是一个MWE。

#!/usr/bin/env python3
import io
import pathlib
import typing
def foobar(file_like_obj: typing.Union[pathlib.Path, typing.IO]):
with file_like_obj.open('w') as handle:
handle.write('foobar')

if __name__ == '__main__':
p = pathlib.Path.home() / 'my.txt'
foobar(p)
sio = io.StringIO()
foobar(sio)

第二次调用foobar()会导致这个错误:

AttributeError: '_io.StringIO' object has no attribute 'open'
我所知道的防止显式类型检查的一种类似python的方法是使用try-except块。但是这会破坏我的with块。

@tripleee的评论让我想到了这个方法,我不会把它称为解决方案,因为它不适合我开始的问题中的所有需求。但对我来说,这似乎是一个很好的妥协。

我结合了递归调用和try..except块。递归是因为我不想把这个功能分离成第二个函数。

#!/usr/bin/env python3
import io
import pathlib
import typing
def foobar(file_like_obj: typing.Union[pathlib.Path, typing.IO]):
print('foobar(): called')
try:
with file_like_obj.open('w') as handle:
print('re-call myself')
foobar(handle)
except AttributeError:
file_like_obj.write('foobar')

if __name__ == '__main__':
p = pathlib.Path.home() / 'my.txt'
foobar(p)
sio = io.StringIO()
foobar(sio)

输出
foobar(): called
re-call myself
foobar(): called
foobar(): called

最新更新