python - 如何编写一个满足typing.TextIO 的类文件?

标签 python type-hinting mypy python-typing

在编写实现类文件接口(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.83.93.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/

    相关文章:

    python - mypy 提示扩展基类的属性类型

    python - 从 bash 将参数传递给 python 函数

    php - PHP 7 中属性的类型提示?

    python - 对于我的想法,是否有更清晰的 Regex 表达式?

    python - python 中 COM 对象的正确类型提示是什么?

    python - 如何使用类型提示指定 "nullable"返回类型

    python-3.x - 带有异常处理的 Python 类型

    python - 如何使用 mypy 键入检查不能是日期时间的日期?

    python - 计算多组数据的平均值(性能问题)

    python - 使用应用程序工厂时反射(reflect)数据库引擎