python-3.x - python 3.7.0 mypy 0.641 使用 UserList 扩展 pythons 的列表?

标签 python-3.x mypy

我正在尝试用一些自定义方法扩展 pythons 的 list,为此我 我正在创建一个继承自 UserList 的类。

我不确定什么是正确的方法,我想让 mypy 玩 与 UserList 配合得很好。

我咨询了cpython UserList docs并在 mypy 中搜索 UserList 但找不到任何内容。

使用:

  • mypy 0.641
  • python 3.7.0

这是我想要实现的目标的一个最小示例

from collections import UserList
from typing import List, Optional, Union


class A:
    ...


class B:
    ...


class C:
    ...


TMessage = Union[A, B, C]


class MyList(UserList):
    """Minimal example"""

    def __init__(self, data: Optional[List[TMessage]] = None) -> None:
        self.data: List[TMessage] = []
        if data:
            self.data = data[:]

    def get_last(self) -> TMessage:
        return self.data[-1]

    # other methods to be added ...


some_data = [A(), B(), C(), C(), B(), A()]
my_list_a = MyList(some_data)
my_list_b = MyList(some_data)

my_list_b = my_list_a[3:]

Mypy报错如下

~/tmp ❯❯❯ mypy mypy_userlist.py

mypy_userlist.py:34: error: Argument 1 to "MyList" has incompatible type "List[object]"; expected "Optional[List[Union[A, B, C]]]"
mypy_userlist.py:35: error: Argument 1 to "MyList" has incompatible type "List[object]"; expected "Optional[List[Union[A, B, C]]]"
mypy_userlist.py:37: error: Incompatible types in assignment (expression has type "MutableSequence[Any]", variable has type "MyList")

我可以将 # type: ignore 添加到冲突行,但我想 避免这种情况。

使用自定义方法扩展 python 列表的正确方法是什么 让 mypy 开心?

最佳答案

我是 MyPy 的新手,但我认为您有两个问题。首先是列表是可变的,因此尽管您的列表对象 some_data 满足代码中所需的结构,但没有理由不是 A 类型的对象,BC 稍后无法添加到其中,这意味着在编译 tile 时,Mypy 无法确保

my_list_a = MyList(some_data) 

是一个有效的赋值。 (查看 Mypy 文档的常见问题部分 here 以获得更多讨论)

您可以通过显式注释 some_data 来解决此问题:

some_data : List[TMessage] = [A(), B(), C(), C(), B(), A()]

第二个问题会在您修复此问题时弹出,当您尝试使用切片分配两个列表时。 MyPy 不知道您的 slice 函数将返回什么,并且会提示不兼容的类型。

要解决此问题,您可以在您的类中显式实现切片功能。

def __getitem__(self, slice_indices) -> 'MyList':
     return self.data[slice_indices]

关于python-3.x - python 3.7.0 mypy 0.641 使用 UserList 扩展 pythons 的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53209814/

相关文章:

python-3.x - 为什么 Cygwin 在 Windows 上找不到已安装的 python 模块?

python - 有没有什么方法可以匹配以一个字符串开头但*不*以另一个字符串开头的正则表达式?

Python 3 : Set namespace for dynamic classes

python - 如何绘制单个 3D 点?

python - 如何在包级别禁用 mypy 错误代码?

python - mypy 泛型可以表示将返回序列类型作为参数传递吗?

python - 如何注释数据类中的字段类型与其__init__的类型不同?

Python - 从文本文件中计算键值对

python - Mypy 是否忽略构造函数?

python - 获取与静态类型检查器一起使用的 TypedDict 值类型的函数