Мой родительский класс наследует list
и добавляет несколько методов, которые возвращают элементы в этом списке. Мой дочерний класс представляет собой последовательность объектов (все одного типа). Как ввести подсказку дочернему (Inventory
) классу, чтобы сообщить средству проверки типов (например, PyCharm), что метод фильтра возвращает последовательность объектов Car
?
Я переписал отрывок из моего кода ниже. Надеюсь, я не упростил этот пример.
from dataclasses import dataclass
class DB(list):
def filter(self, **kwargs):
"""Returns all matching items in the DB.
Args:
**kwargs: Attribute/Value pairs.
"""
def is_match(item):
"""Do all the attribute/value pairs match for this item?"""
result = all(getattr(item, k) == v
for k, v in kwargs.items())
return result
return type(self)(x for x in self if is_match(x))
@dataclass
class Car:
make: str = 'Tesla'
class Inventory(DB[Car]):
# Type hint the Inventory class as a sequence of Car objects?
pass
# Type hint the parent filter() method???
filter : (make: str) -> Inventory[Inventory]
inventory = Inventory((Car(), Car('Jaguar')))
inventory[0].make # Autocomplete is working here.
filtered = inventory.filter(model='X')
filtered[0].? # Pycharm should know that this is a Car, and autocomplete attributes.
EDITED: -> Инвентарь[Инвентарь] и форматирование.
Вкратце: как напечатать подсказку метода класса вне класса.
@ Рой Коэн: Да
Затем напишите что-то вроде T = typing.TypeVar('T'); class DB(list[T]): ...
(я мало что знаю о подсказках типов Python, так что это может не сработать, но попробуйте).
@RoyCohen: Вау, это работает! Удивительный.
Чтобы это работало, класс DB
должен быть универсальным, поэтому вместо:
class DB(list): ...
Должен быть:
from typing import TypeVar
T = TypeVar('T')
class DB(list[T]): ...
Обновлено:
В python 3.5 - 3.8 вы не можете сделать list[T]
, поэтому вы должны сделать:
from typing import TypeVar, List
T = TypeVar('T')
class DB(List[T]): ...
спасибо @ChaimG за предложение.
Это работает так же, как и в Python 3.9. Для Python 3.5–3.8 используйте typing.List[T]
вместо list[T]
.
@ChaimG Требует ли это независимого подкласса от list
? Например. class DB(typing.List[T], list): ...
У вас есть доступ к классу
DB
? т.е. Вы можете изменить код, который определяет его?