python 3.7.0 mypy 0.641 使用 UserList 扩展 pythons' 列表?
python 3.7.0 mypy 0.641 extending pythons' list with UserList?
我正在尝试使用一些自定义方法来扩展 pythons' list
,为此我
正在创建一个 class 继承自 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
、B
或 C
之后无法添加,意思是在编译 tile 时,Mypy 无法确保
my_list_a = MyList(some_data)
是一个有效的分配。 (查看 Mypy 文档的常见问题部分 here 以获得更多讨论)
您可以通过显式注释 some_data
:
来解决这个问题
some_data : List[TMessage] = [A(), B(), C(), C(), B(), A()]
当您修复此问题时,当您尝试使用切片分配两个列表时,会弹出第二个问题。 MyPy 不会知道您的切片函数 return 并且会抱怨不兼容的类型。
要解决此问题,您可以在 class 中明确实现切片功能。
def __getitem__(self, slice_indices) -> 'MyList':
return self.data[slice_indices]
我正在尝试使用一些自定义方法来扩展 pythons' list
,为此我
正在创建一个 class 继承自 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
、B
或 C
之后无法添加,意思是在编译 tile 时,Mypy 无法确保
my_list_a = MyList(some_data)
是一个有效的分配。 (查看 Mypy 文档的常见问题部分 here 以获得更多讨论)
您可以通过显式注释 some_data
:
some_data : List[TMessage] = [A(), B(), C(), C(), B(), A()]
当您修复此问题时,当您尝试使用切片分配两个列表时,会弹出第二个问题。 MyPy 不会知道您的切片函数 return 并且会抱怨不兼容的类型。
要解决此问题,您可以在 class 中明确实现切片功能。
def __getitem__(self, slice_indices) -> 'MyList':
return self.data[slice_indices]