Каковы различия между использованием нескольких подсказок типа or и abc и иерархией наследования в Python?Python

Программы на Python
Anonymous
Каковы различия между использованием нескольких подсказок типа or и abc и иерархией наследования в Python?

Сообщение Anonymous »

Python — динамический язык. Это означает, что типы являются динамическими во время выполнения, и Python использует концепцию Ducktyping.
Это означает, что для любого объекта x можно сделать
  • x.some_function()
  • x.some_property = y
не зная до момента выполнения, имеет ли x атрибут some_property или функцию some_function >.
В 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

Вернуться в «Python»