在编写实现类文件接口的类时,我们可以从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时(使用python3.7.3和mypy0.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
我认为您的第一次尝试实际上是正确的,它只需要您实现所有抽象方法(如错误所示)。你不必把实际的逻辑放在那里。下面的类将完成此任务:
相关问题 更多 >
编程相关推荐