正确输入sys.stdout和文件

问题描述

我正在尝试创建一种方法,该方法可以处理代表文件名,Path对象或已经打开的输出流(sys.stdoutopen('...','w'))的字符串。而且我正在尝试正确设置mypy的类型以进行检查。

到目前为止,我得到了:

import io
from pathlib import Path
from typing import Union,TextIO,Text


def generate(output: Union[Text,Path,TextIO]) -> None:
    if isinstance(output,io.IOBase):
        output.write("data")
    else:
        if isinstance(output,Text):
            output = Path(output)
        with output.open("w") as output_file:
            output_file.write("data")

但是mypy一直在抱怨

Item "TextIO" of "Union[Path,TextIO]" has no attribute "open"

AFAIK,TextIO是用于文本文件的正确类型,但是无法对此类型进行isinstance检查。代码结构确保了在发生错误时,我们不能拥有TestIO对象,因为它是在上一个分支中处理过的。

如何在这里标记所有类型?

解决方法

由于Mypy理解open检查并在一个位置调用isinstance,因此可以重写以下代码以在Path分支中隔离write

import io
from pathlib import Path
from typing import Union,TextIO,Text
from contextlib import ExitStack


def generate(output: Union[Text,Path,TextIO]) -> None:
    with ExitStack() as stack:
        if isinstance(output,Text):
            output = Path(output)
        if isinstance(output,Path):
            output = stack.enter_context(output.open("w"))
        output.write("data")

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...