#python #mypy
#python #mypy
Вопрос:
Как мне определить тип, который инкапсулирует / описывает поведение / сигнатуру определенного модуля?
Проблема возникает из-за того, что мне приходится спать в моем коде, и я хочу абстрагироваться от этого. Я хочу внедрить макет для time
библиотеки (вполне вероятно, что позже мне понадобятся другие функции time
), и я также хочу определить типы, чтобы включить статическую проверку типов (MyPy используется для проверки типов). Я также хотел бы, чтобы моя среда разработки имела надлежащее автозаполнение и документацию (что было бы в случае, если он может правильно угадать «тип»)
В настоящее время у меня есть следующий код, который работает и проходит мои проверки, однако это просто игнорирует ошибку MyPy (time не является допустимым типом):
import time
[other relevant imports]
...
@dataclass
class RPUService:
config: RPUConfig
_time: time = time # type: ignore[valid-type]
...
def some_method(self):
self._time.sleep(self.config.sleepytime)
Я также могу написать _time
определение следующим образом:
from types import ModuleType
_time: ModuleType = time
Или аналогично с Any
:
from typing import Any
_time: Any = time
Оба они действительны, но это лишает мою среду IDE возможности распознавать self._time
как time
библиотеку. (Или что-то похожее на time
библиотеку)
Я мог бы определить a Protocol
с сигнатурой time.sleep
, но я бы предпочел не иметь накладных расходов на поддержание такого Protocol
. (PEP-544)
Итак, мой вопрос: как мне определить тип, который инкапсулирует / описывает поведение определенного модуля?
(Если что-то неясно, пожалуйста, спросите)
Комментарии:
1. Способность вашей IDE автоматически заполнять ваш код не имеет ничего общего с mypy. Я думаю
_time = time
, это легко понять для IDE, но при объявлении_time
определенного типа эта информация имеет более высокий приоритет, чем определение= time
, поэтому она больше не автоматически заполняется какtime
, а как «объект объявленного типа».2. Я бы выбрал протокольный подход. Похоже, это именно то, что вам нужно: «что-то, у чего есть метод ожидания, который принимает один аргумент с плавающей запятой». Вам даже не нужно определять все функции модуля time, а только те, которые вам нужны.
3. @Wombatz Хм, ну, на данный момент мне нужно только «что-то, что спит», поэтому протокол будет тривиальным для создания, однако он также скрывает всю остальную функциональность
time
. Поэтому, если в будущем коллега захочет использовать функциональность изtime
, ему / ей нужно будет знать, чтобы расширить протокол, что может быть не так просто, как хотелось бы. Если есть возможность сделать это без дополнительной абстракции, которую привносит протокол, я бы предпочел такой вариант.4. @NiklasMertsch IDE, вероятно, выводит тип из присваивания, чтобы обеспечить автоматическое завершение, если тип не указан, и один из способов заставить это работать (иметь автозаполнение и никаких ошибок MyPy) — полностью удалить ввод текста. (
_time = time
хотя это недопустимое объявление@dataclass
, мне пришлось бы писать__init__
вручную). Это решение, однако я хотел бы узнать, как «решить» это с помощью статической типизации.5. Есть ли необходимость в аннотации типа вообще? Если вы хотите автозаполнение, а ваша IDE выполняет автозаполнение без аннотаций, то по какой причине вы это делаете? Единственными «хорошими» аннотациями, которые я могу представить для этого случая, было бы что-то вроде
_time: get_annotation(time)
, но такой функциональности не существует. Кроме того, вам не нужно «что-то, что имеет сигнатурыtime
модуля», но вам нужен »time
модуль», так зачем его явно аннотировать, если в любом случае это всегда один и тот же объект?