在 Python 中注释 "file type" 的正确方法

The correct way to annotate a "file type" in Python

根据 PEP 484,在 Python 的现代版本中,可以使用函数注释进行静态类型分析。通过输入模块可以轻松做到这一点。

现在我想知道如何为“文件流”提供“类型提示”。

def myfunction(file: FILETYPE):
    pass

with open(fname) as file:
    myfunction(file)

我会插入什么作为 FILETYPE

使用 print(type(file)) returns <class '_io.TextIOWrapper'> 根本不清楚。

没有通用的“文件”类型吗?

我想你想要io.IOBase,“[t]所有I/O classes的抽象基础class,作用于字节流。”

请注意,这还包括 in-memory 流,例如 io.StringIOio.BytesIO。有关详细信息,请阅读 module io 上的文档。

您可以使用 typing.IOtyping.TextIOtyping.BinaryIO 来表示不同类型的 I/O 流。引用 documentation:

сlass typing.IO
class typing.TextIO
class typing.BinaryIO

Generic type IO[AnyStr] and its subclasses TextIO(IO[str]) and BinaryIO(IO[bytes]) represent the types of I/O streams such as returned by open().

或者这个:

from typing import TextIO # or IO or BinaryIO

def myfunction(file: TextIO ):
    pass

这个

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from typing import TextIO # or IO or BinaryIO

def myfunction(file: 'TextIO'):
    pass

第二种方法将避免在执行期间导入 class。尽管 python 仍然需要在执行期间导入 TYPE_CHECKING,但最好避免导入 classes 仅用于类型提示:(1) 不执行(仅解析) , (2) 它可以避免循环导入

typeshed 有一个 SupportsRead 协议:

from __future__ import annotations
from typing import TYPE_CHECKING, AnyStr

if TYPE_CHECKING:
    from _typeshed import SupportsRead


def takes_readable_str(fo: SupportsRead[str]):
    return fo.read()

def takes_readable_bytes(fo: SupportsRead[bytes]):
    return fo.read()

def takes_readable_any(fo: SupportsRead[AnyStr]):
    return fo.read()