Перед тем, как вы погрузитесь, вот мой вопрос: как я могу использовать подсказки типов в подклассе для указания другого типа в атрибуте экземпляра?
Если вам неясно, что это значит, прочитайте ниже,где я нарисовал пример для разъяснения вещей.
Полное объяснение
У меня есть абстрактный класс Foo
и подкласс Foo
с именем SubclassOfFoo
.
Foo
имеет абстрактный метод get_something
, который возвращает объект типа Something
.
Something
имеет подкласс с именем SubclassOfSomething
.SubclassOfSomething
имеет дополнительный метод something_special
.
SubclassOfFoo
переопределяет get_something
для возврата объекта типа SubclassOfSomething
.Затем SubclassOfFoo
пытается использовать метод SubclassOfSomething
something_special
.
Однако в настоящее время проверки моего PyCharm сообщают Unresolved attribute reference 'something_special' for class 'Something'
.Я пытаюсь найти правильный способ исправить это.
Это все очень запутанно, поэтому я сделал хороший небольшой фрагмент кода, чтобы помочь здесь:
from abc import ABC, abstractmethod
class Something:
def __init__(self):
self.attr = 0
class SubclassOfSomething(Something):
def __init__(self):
Something.__init__(self)
def something_special(self):
self.attr = 1
class Foo(ABC):
def __init__(self):
self.my_class = self.get_something()
@abstractmethod
def get_something(self) -> Something:
pass
class SubclassOfFoo(Foo):
def __init__(self):
Foo.__init__(self)
def get_something(self) -> SubclassOfSomething:
return SubclassOfSomething()
def do_something_special(self):
self.my_class.something_special()
В основном, вЧтобы все получилось, я могу сделать одну из следующих вещей:
- Удалить подсказку типа при возврате
get_something
в пределах Foo
- Использовать подсказку типав
SubclassOfFoo
для self.my_class
, чтобы прояснить ситуацию - Использовать дженерики?
Вариант № 1 - это то, чего я пытаюсь избежать
Вариант № 2 - это вариантнеплохо, но я не могу понять это
Вариант №3 также является вариантом.
Я также открыт для других вариантов, так как я уверен, что есть лучший способ.
Не могли бы вы помочь мне выяснить, как правильно с этим справиться?
Что я уже пробовал
Чтобы эмулировать вариант №2, я попытался использовать typing.Type
, как предлагается здесь: Подкласс в подсказке типа
Однако, это не сработало для меня.