我正在尝试创建一个方法,该方法可以处理表示文件名、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")