为 base class for subclasses 中定义的接口使用不同的固定类型
Use a different fixed type for interfaces defined in the base class for subclasses
我有一个 BaseList
容器,可以将 BaseItem
作为物品。然后我派生了一个新列表 CustomList
,我希望它包含 CustomItem
。
如何在 BaseList
中键入方法以接受 BaseItem
的许多方法。并告诉它使用 CustomItem
派生列表 CustomList
?
这是我目前的代码:
from __future__ import annotations
from typing import List, Union, Iterator, overload
class BaseItem:
pass
class BaseList:
def __init__(self) -> None:
self.items: List[BaseItem] = []
def add_item(self, item: BaseItem) -> None:
self.items.append(item)
def __iter__(self) -> Iterator[BaseItem]:
return iter(self.items)
class CustomItem(BaseItem):
def __init__(self, value: int) -> None:
self.value: int = value
class CustomList(BaseList):
def sum(self) -> int:
# mypy error: "BaseItem" has no attribute "value"
return sum(item.value for item in self)
# no error, but it should say: incompatible type; expected "CustomItem".
CustomList().add_item(BaseItem())
container = CustomList()
container.add_item(CustomItem(10))
for item in container:
# mypy error: `"BaseItem" has no attribute "value"`
print(item.value)
问题
如何定义类型 A
并在 BaseList
中说它应该解析为 BaseItem
而在 CustomList
中它应该解析为 CustomItem
?
到目前为止已经试过了
我尝试将 TypeVar 与 bounds 属性一起使用,但似乎没有成功。
约束
我有不止一个子class所以我不想用不同的类型重新实现所有这些方法。此外,还有更多此类方法存在类似问题,例如 __contains__
、__getitem__
、class 特定项目等
类型提示也应由 PyCharm 解决,因为目标是在那里获得正确的代码。
制作 BaseList class 通用:
class BaseItem:
pass
T = TypeVar('T', bound=BaseItem)
class BaseList(Generic[T]):
def __init__(self) -> None:
self.items: List[T] = []
def add_item(self, item: T) -> None:
self.items.append(item)
def __iter__(self) -> Iterator[T]:
return iter(self.items)
class CustomItem(BaseItem):
def __init__(self, value: int) -> None:
self.value: int = value
class CustomList(BaseList[CustomItem]):
def sum(self) -> int:
reveal_type(self.items) # Mypy: Revealed type is "builtins.list[CustomItem*]"
return sum(item.value for item in self)
我有一个 BaseList
容器,可以将 BaseItem
作为物品。然后我派生了一个新列表 CustomList
,我希望它包含 CustomItem
。
如何在 BaseList
中键入方法以接受 BaseItem
的许多方法。并告诉它使用 CustomItem
派生列表 CustomList
?
这是我目前的代码:
from __future__ import annotations
from typing import List, Union, Iterator, overload
class BaseItem:
pass
class BaseList:
def __init__(self) -> None:
self.items: List[BaseItem] = []
def add_item(self, item: BaseItem) -> None:
self.items.append(item)
def __iter__(self) -> Iterator[BaseItem]:
return iter(self.items)
class CustomItem(BaseItem):
def __init__(self, value: int) -> None:
self.value: int = value
class CustomList(BaseList):
def sum(self) -> int:
# mypy error: "BaseItem" has no attribute "value"
return sum(item.value for item in self)
# no error, but it should say: incompatible type; expected "CustomItem".
CustomList().add_item(BaseItem())
container = CustomList()
container.add_item(CustomItem(10))
for item in container:
# mypy error: `"BaseItem" has no attribute "value"`
print(item.value)
问题
如何定义类型 A
并在 BaseList
中说它应该解析为 BaseItem
而在 CustomList
中它应该解析为 CustomItem
?
到目前为止已经试过了
我尝试将 TypeVar 与 bounds 属性一起使用,但似乎没有成功。
约束
我有不止一个子class所以我不想用不同的类型重新实现所有这些方法。此外,还有更多此类方法存在类似问题,例如 __contains__
、__getitem__
、class 特定项目等
类型提示也应由 PyCharm 解决,因为目标是在那里获得正确的代码。
制作 BaseList class 通用:
class BaseItem:
pass
T = TypeVar('T', bound=BaseItem)
class BaseList(Generic[T]):
def __init__(self) -> None:
self.items: List[T] = []
def add_item(self, item: T) -> None:
self.items.append(item)
def __iter__(self) -> Iterator[T]:
return iter(self.items)
class CustomItem(BaseItem):
def __init__(self, value: int) -> None:
self.value: int = value
class CustomList(BaseList[CustomItem]):
def sum(self) -> int:
reveal_type(self.items) # Mypy: Revealed type is "builtins.list[CustomItem*]"
return sum(item.value for item in self)