在Python中注释"文件类型"的正确方法

pau*_*l23 17 python type-hinting python-3.5

根据PEP 484,在现代版本的Ppython中,可以使用函数注释进行静态类型分析.通过打字模块可以轻松实现这一点.

现在我想知道如何向"文件流"提供"类型提示".

def myfunction(file: FILETYPE):
    pass

with open(fname) as file:
    myfunction(file)
Run Code Online (Sandbox Code Playgroud)

我会插入FILETYPE什么?

使用根本不明确的print(type(file))回报<class '_io.TextIOWrapper'>.

是不是有通用的"文件"类型?

Eug*_*ash 11

您可以使用typing.IO,typing.TextIOtyping.BinaryIO表示不同类型的I/O流.引用文档:

班级打字.IO

    I/O流类型的包装器命名空间.

    这定义了泛型类型IO[AnyStr]和别名TextIO,     分别BinaryIO用于和.这些代表I/O流的类型,例如     返回的.
IO[str]IO[bytes]
open()

    这些类型也直接访问的typing.IO,typing.TextIO
    typing.BinaryIO.

  • @lead-free 我相信弃用注释仅适用于 *`typing.io` 命名空间*。请参阅[此](https://bugs.python.org/issue42001)和[此](https://bugs.python.org/issue38291)。 (10认同)
  • @EugeneYarmash 是对的。以下是来自 [docs](https://docs.python.org/3/library/typing.html#typing.IO) 的实际弃用消息:“`typing.io` *namespace* 已弃用并将被删除. **这些类型应该直接从** `typing` **导入。**" (2认同)

Sto*_*ica 9

我想您想io.IOBase:“为所有I / O类提供抽象基类,作用于字节流。”

请注意,这还包括诸如io.StringIO和的内存中流io.BytesIO。有关详细信息,请阅读模块io上的文档。


tot*_*ico 5

要么这样:

from typing import TextIO # or IO or BinaryIO

def myfunction(file: TextIO ):
    pass
Run Code Online (Sandbox Code Playgroud)

或者这个

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

def myfunction(file: 'TextIO'):
    pass
Run Code Online (Sandbox Code Playgroud)

第二种方法将避免在执行期间导入类。尽管 pythonTYPE_CHECKING在执行期间仍然需要导入,但避免仅为类型提示导入类是一个好习惯:(1) 不会被执行(只是解析),以及 (2)它可以避免循环导入

  • 鉴于类型暗示 PEP [484](https://www.python.org/dev/peps/pep-0484/#rationale-and-goals) 的目标之一,我不明白为什么这是一个好的实践以避免导入类型提示。 (2认同)