Перегрузка печатать с Python * args в суперклассе - PullRequest
1 голос
/ 29 мая 2019

У меня есть простой базовый класс:

class Base:
  def get(self, *names: str) -> Any:
    # implementation not important

Я пытаюсь определить подкласс с более строгой типизацией для некоторых случаев использования:

from typing import overload, Any
from typing_extensions import Literal

class Sub(Base):
  # mypy error here: Signature of "get" incompatible with supertype "Base"
  @overload
  def get(self, *names: Literal['Something']) -> Something: ...
  @overload
  def get(self, *names: Literal['Else']) -> Else: ...
  def get(self, *names: str) -> Any:
    return super().get(*names)

Однако я получаю сообщение об ошибке, указанное в приведенном выше коде: Signature of "get" incompatible with supertype "Base". Я пробовал другие формы для аргументов перегрузки для класса Sub, но все выдают похожую ошибку.

Есть ли в любом случае метод базового класса, который принимает *args, для обеспечения определенных перегрузок в подклассе при передаче литеральных значений?

1 Ответ

0 голосов
/ 29 мая 2019

Правильные значения для Sub должны выглядеть примерно так:

class Sub(Base):
  @overload
  def get(self, __name: Literal['Something']) -> Something: ...
  @overload
  def get(self, __name: Literal['Else']) -> Else: ...
  @overload
  def get(self, *names: str) -> Any: ...
  def get(self, *names: str) -> Any:
    return super().get(*names)

Здесь есть несколько изменений по сравнению с вопросом.

1) Мы определяем дополнительную перегрузку, котораяимеет типы, идентичные реализации.Документы python для @overload объясняют это: «[определение без перегрузки] используется во время выполнения, но должно игнорироваться средством проверки типов.»

2) Никтобудет передавать один и тот же литерал более одного раза, поэтому мы могли бы также изменить *names на __name.Начальные подчеркивания указывают на то, что name является «только позиционным», как описано в документах mypy :

# An argument can be declared positional-only by giving it a name
# starting with two underscores:
def quux(__x: int) -> None:
    pass

quux(3)  # Fine
quux(__x=3)  # Error

С вышеуказанными изменениями, при желании, исключите проверки типов Sub класса.

...