python 3.7.0 mypy 0.641用UserList扩展了pythons的列表?

时间:2018-11-08 14:30:22

标签: python-3.x mypy

我正在尝试通过一些自定义方法扩展python'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开心?

1 个答案:

答案 0 :(得分:2)

我是MyPy的新手,但我认为您有两个问题。首先是列表是可变的,因此尽管您的列表对象some_data满足代码中所需的结构,但没有理由使用非AB或{{ 1}}以后无法添加到它,这意味着在编译磁贴中,Mypy无法确保

C

是有效的分配。 (有关更多讨论,请参阅Mypy文档here的“常见问题”部分)

您可以通过显式注释my_list_a = MyList(some_data) 来解决此问题:

some_data

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

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

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