Использование подписи реализованного метода в производном классе для унаследованного метода из базового класса в наследоPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Использование подписи реализованного метода в производном классе для унаследованного метода из базового класса в наследо

Сообщение Anonymous »

Предположим, у нас есть сценарий наследования шаблона метода шаблона. Я использую пример с библиотекой запросов.
import abc
import json
import requests
from typing import Dict, Any

class Base(abc.ABC)
@abc.abstractmethod
def call(self, *args, **kwargs) -> requests.Response:
raise NotImplementedError

def safe_call(self, *args, **kwargs) -> Dict[str, Any]:
try:
response = self.call(*args, **kwargs)
response.raise_for_status()
return response.json()
except json.JSONDecodeError as je: ...
except requests.exceptions.ConnectionError as ce: ...
except requests.exceptions.Timeout as te: ...
except requests.exceptions.HTTPError as he: ...
except Exception as e: ...
return {"success": False}

class Derived(Base):
def call(self, url: str, json: Dict[str, Any], timeout: int, retries: int) -> requests.Response:
# actual logic for making the http call
response = requests.post(url, json=json, timeout=timeout, ...)
return response

который будет использоваться как
executor = Derived()
response = executor.safe_call(url='https://example.com', json={"key": "value"}, ...)

Есть ли способ прикрепить подпись Derived.call к Derived.safe_call, чтобы современные автозаполнение IDE и средства проверки типов работали?
Поскольку это ужасно похоже на шаблон декоратора, я попробовал использовать functools.update_wrapper в __init__, но это не помогло
AttributeError: 'method' object has no attribute '__module__'

У меня есть несколько вариантов, но я не могу найти никаких рекомендаций по этой проблеме.
  • Я может пойти по пути метакласса, чтобы изменить атрибуты подписи и строки документации до того, как класс будет полностью создан. Однако это может не работать с IDE.
  • Я могу определить файл-заглушку .pyi и поддерживать его вместе с основным кодом.
class Derived(Base):
def safe_call(self, url: str, json: Dict[str, Any], timeout: int, retries: int) -> Dict[str, Any]: ...
  • Полностью измените дизайн на другой

    < li>(Изменить: добавлен первый ответ) (Ab) используйте @typing.overload
< pre class="lang-py Prettyprint-override">class Derived(Base):
@typing.overload
def safe_call(self, url: str, json: Dict[str, Any], timeout: int, retries: int) -> Dict[str, Any]:
...

def call(self, url: str, json: Dict[str, Any], timeout: int, retries: int) -> requests.Response:
# actual logic for making the http call
response = requests.post(url, json=json, timeout=timeout, ...)
return response


Подробнее здесь: https://stackoverflow.com/questions/687 ... ethod-from
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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