sys.stdout 和文件的正确输入
Proper typing for sys.stdout and files
我正在尝试创建一个方法来处理表示文件名的字符串、Path
对象或已经打开的输出流(sys.stdout
、open('...', '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
对象,因为它已在上一个分支中处理过。
我应该如何标记这里的所有类型?
这段代码可以重写如下,在 Path 分支中隔离 open
,因为 Mypy 理解 isinstance
检查,并在一个地方调用 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")
我正在尝试创建一个方法来处理表示文件名的字符串、Path
对象或已经打开的输出流(sys.stdout
、open('...', '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
对象,因为它已在上一个分支中处理过。
我应该如何标记这里的所有类型?
这段代码可以重写如下,在 Path 分支中隔离 open
,因为 Mypy 理解 isinstance
检查,并在一个地方调用 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")