Это означает, что для любого объекта x можно сделать
- x.some_function()
- x.some_property = y
В Python есть наследование классов. Он также имеет концепцию «абстрактных базовых классов», предоставляемую модулем abc.
Этот модуль предоставляет декоратор @abstractmethod. Декоратор предотвращает создание экземпляров подклассов во время выполнения без того, чтобы эти подклассы предварительно предоставили реализации для любых методов, помеченных как абстрактные с помощью @abstractmethod.
Это всего лишь часть логики защиты, которая запускается во время выполнения, когда создается экземпляр класса. Он ведет себя примерно так, как если бы проверка необходимых методов во время выполнения происходила в функции __init__.
Этот вопрос касается обеих этих концепций, но особенно в контексте подсказок типов. Подсказки типов позволяют статическим анализаторам предоставлять помощь при разработке в IDE. Очевидным примером является языковой сервер Python и расширение Python для VS Code.
Подсказки типов имеют и другие цели и способы использования, но в этом контексте меня интересует взаимодействие с инструментами статического анализа. in.
Рассмотрим пример иерархии наследования.
class AbstractMessage():
pass
class GetterMessage(AbstractMessage):
pass
class SetterMessage(AbstractMessage):
pass
В этом примере я определил два типа сообщений, которые наследуются от абстрактного базового класса. Однако нет никаких оснований для существования этого ABC, и код, использующий GetterMessage и SetterMessage, без него не будет работать по-другому.
Вот два возможных варианта. способы реализации функции, которая может возвращать любой тип.
def example_function() -> GetterMessage|SetterMessage:
pass
def example_function() -> AbstractMessage:
pass
def example_code_block():
return_value = example_function()
return_value. #
Следующие простые тесты показывают предложения по атрибутам my_object или my_object_2, сделанные статическим анализатором VS Code/Pylance.
(Этот тест предназначен только для VS Code с Pylance, независимо от того, какие версии этого программного обеспечения в данный момент установлены на машине, на которой я запускал эти тесты, и не обязательно дает общий ответ.)
Потенциально интересно то, что синтаксис or Type1|Type2 предоставляет полный набор возможных опций, тогда как возвращаемый тип ABC иерархии наследования этого не дает.
class Type1():
def common_function():
pass
def function_1():
pass
class Type2():
def common_function():
pass
def function_2():
pass
class AbstractBaseType():
def abstract_base_type_function():
pass
class ConcreteType1(AbstractBaseType):
def common_function():
pass
def function_1():
pass
class ConcreteType2(AbstractBaseType):
def common_function():
pass
def function_2():
pass
def example_function_1(input: str) -> Type1 | Type2:
if input == 'Type1':
return Type1()
else:
return Type2()
def example_function_2(input: str) -> AbstractBaseType:
if input == 'Type1':
return ConcreteType1()
else:
return ConcreteType2()
def test_function():
my_object_1 = example_function_1()
my_object_2 = example_function_2()
my_object_1. #
Подробнее здесь: https://stackoverflow.com/questions/787 ... and-an-inh