Mar*_*ery 57 python type-hinting
是否有任何正确的类型提示用于Python中的文件或类文件对象?例如,我如何键入提示此函数的返回值?
def foo():
return open('bar')
Run Code Online (Sandbox Code Playgroud)
Way*_*ner 73
对于分别以文本模式或二进制模式打开的文件,请使用typing.TextIO
或typing.BinaryIO
类型.
来自文档:
类
typing.io
I/O流类型的包装器命名空间.
这定义了泛型类型
IO[AnyStr]
和别名TextIO
,BinaryIO
分别用于IO[str]
和IO[bytes]
.这些表示I/O流的类型,例如返回的open()
.
Cha*_*iam 24
简短的回答:
from typing import TextIO
不仅仅是from typing import *
.IO
意味着文件没有指定什么样的TextIO
或BinaryIO
如果您知道类型举个例子:
from typing import BinaryIO
def binf(inf: BinaryIO):
pass
with open('x') as f:
binf(f)
Run Code Online (Sandbox Code Playgroud)
给出了一个检查错误(在 PyCharm 中) Expected type 'BinaryIO', got 'TextIO' instead
如果您要注释参数的类型,请考虑不使用typing.IO
、typing.TextIO
或typing.BinaryIO
。
它们可能会对调用者造成过度限制,因为它们包含您通常并不真正需要的内容,例如.encoding
和.newlines
。
相反,请考虑定义您自己的typing.Protocol
. 这让您只需要您实际需要的“类似文件”界面的部分。
因此,例如,不要这样做:
def foo(file_like: typing.TextIO) -> None:
read_str = file_like.read()
# ...
Run Code Online (Sandbox Code Playgroud)
考虑这样做:
class TextFileLike(typing.Protocol):
def read() -> str:
...
def foo(file_like: TextFileLike) -> None:
read_str = file_like.read()
# ...
Run Code Online (Sandbox Code Playgroud)
一些 Python 核心开发人员在https://github.com/python/typing/discussions/829上提供了此建议。
这些 [
typing.IO
、typing.TextIO
和typing.BinaryIO
] 类旨在模拟“文件对象”的概念,但是当您开始了解“文件对象”在 Python 库系统中的实际使用方式时,您很快就会意识到,其中存在大量变化您到底可以用它们做什么。
此策略的缺点typing.Protocol
是它限制了您以后更改实施的能力。例如,如果您稍后决定要调用.readline()
而不是.read()
,并且您没有将其包含.readline()
在原始 中typing.Protocol
,则需要对界面进行重大更改。换句话说,这是一个权衡,要么预先对调用者限制过多而导致 API 可用性问题,要么接口与实现耦合得太紧而导致破坏性更改。