在编写实现类文件接口(interface)的类时,我们可以从 io
继承抽象基类之一。模块,例如 TextIOBase
,如图 Adapt an iterator to behave like a file-like object in Python .
另一方面,在类型注释中,我们应该使用派生自 typing.IO
的类。 (例如 TextIO
)来表示这样的对象,如 Type hint for a file or file-like object? 所示或 Type-checking issue with io.TextIOBase in a Union .
但是,这似乎不像我预期的那样工作:
import io
import sys
import typing
class MyIO(io.TextIOBase):
def write(self, text: str):
pass
def hello(f: typing.TextIO):
f.write('hello')
hello(sys.stdout) # type checks
hello(open('temp.txt', 'w')) # type checks
hello(MyIO()) # does not type check
在此代码上运行 mypy 时(使用 Python 3.7.3 和 mypy 0.910),我们得到error: Argument 1 to "hello" has incompatible type "MyIO"; expected "TextIO"
题
怎么会
MyIO
类被编写成被接受为类型 typing.TextIO
的函数参数(不只是使用 typing.cast(typing.TextIO, ...)
)?失败的尝试
typing.TextIO
作为基类是不可能的:使用时
class MyIO(typing.TextIO)
:error: Cannot instantiate abstract class "MyIO" with abstract attributes "__enter__", "__exit__", ... and "writelines" (15 methods suppressed)
使用时
class MyIO(io.TextIOBase, typing.TextIO):
:error: Definition of "readlines" in base class "IOBase" is incompatible with definition in base class "IO"
其他几种方法也是如此。
__new__
和注释 typing.TextIO
因为返回类型不起作用:def __new__(cls, *args, **kwargs) -> typing.TextIO:
return super().__new__(cls, *args, **kwargs)
结果是error: Incompatible return type for "__new__" (returns "TextIO", but must return a subtype of "MyIO")
error: Incompatible return value type (got "MyIO", expected "TextIO")
或者这已经可以工作了,而我使用的 Python 和/或 mypy 版本太旧了?使用
--python-version 3.8
或 3.9
或 3.10
然而,作为 mypy 的选项不会改变任何东西。
最佳答案
使用 io.StringIO
反而
import io
import sys
import typing
class MyIO(io.StringIO):
def write(self, text: str):
pass
def hello(f: typing.TextIO):
f.write("hello")
hello(sys.stdout) # type checks
hello(open("temp.txt", "w")) # type checks
hello(MyIO()) # type checks
关于python - 如何编写一个满足typing.TextIO 的类文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69570166/