我读过一些 其他答案 ,它们似乎与现实生活中发生的事情相矛盾。
尝试以下操作:
from typing import IO
from pathlib import Path
example_path = Path(r"D:\Example.txt")
with example_path.open("r") as f:
print(isinstance(f, IO))
with open(example_path) as f:
print(isinstance(f, IO))
它将打印:
False
False
这令人困惑,因为根据
文档
,在我看来,
typing.IO
的真正目的之一是对对象的
IO
类型进行类型检查,这将包括
isinstance()
的使用。为什么不起作用?这不是违背了初衷吗?我在这里缺少什么?
你对于
typing.IO
的理解不完全正确。
typing.IO
本身并不直接用于
isinstance
检查。它是一个
泛型类
,用来表示各种类型的文件类对象,例如文本文件 (
TextIO
) 和二进制文件 (
BinaryIO
)。
问题根源:
-
pathlib.Path.open()
和open()
返回具体的类: 这些函数返回的不是IO
类型,而是更具体的类型,例如TextIOWrapper
(对于文本模式) 或BufferedReader
(对于二进制模式)。这些具体类型是IO
的 子类 ,但并不直接等同于IO
。 -
isinstance
和泛型:isinstance
用于检查对象的类型是否与指定的类型 完全相同 或 是其子类 。由于IO
是一个泛型类,它并不能直接代表具体的文本或二进制文件类型,所以isinstance
检查会返回False
。
解决方案:
为了进行类型提示和检查,你可以使用更具体的类型提示:
from typing import TextIO, BinaryIO
from pathlib import Path
example_path = Path(r"D:\Example.txt")
# 对于文本文件:
with example_path.open("r") as f:
print(isinstance(f, TextIO)) # 输出 True
# 对于二进制文件:
with example_path.open("rb") as f:
print(isinstance(f, BinaryIO)) # 输出 True
总结:
-
typing.IO
用于表示泛型文件类型,不建议直接用于isinstance
检查。 -
使用
TextIO
和BinaryIO
来进行更具体的类型提示和检查。 -
pathlib.Path.open()
和open()
返回的具体类型取决于打开文件的模式。