Python: как использовать подсказки типов в сочетании с `__instancecheck__`Python

Программы на Python
Anonymous
Python: как использовать подсказки типов в сочетании с `__instancecheck__`

Сообщение Anonymous »


Позвольте мне построить мой вопрос шаг за шагом, используя глупый пример: у меня есть функция roast(obj), которая работает с объектами, которые являются утками, т. е. все, что "может крякать":

defoast(obj): print(f"> сказала утка перед тем, как ее зажарили\n - (печальный) конец.") Я хочу улучшить функцию, прежде всего проверяя, является ли объект уткой. Чтобы облегчить проверку того, является ли obj уткой, я написал следующее:

из abc import ABCMeta класс DuckMeta(ABCMeta): @classmethod защита __instancecheck__(cls, экземпляр): return callable(getattr(instance, "шарлатан", None)) класс Duck(metaclass=DuckMeta): защита шарлатан(сам): вернуть «Кря!» Метод __instancecheck__ в метаклассе реализует логику проверки того, является ли instance уткой, а класс Duck, ну, , очень простой класс уток. Отлично, теперь я могу обновить roast():

defoast(obj): если не isinstance(obj, Duck): поднять TypeError(f"Объект типа {type(obj)} не является уткой!") print(f"> сказала утка перед тем, как ее зажарили\n - (печальный) конец.") Отлично! В интерпретаторе я теперь могу сделать:

>>> жаркое(Утка()) > сказала утка перед тем, как ее зажарить - (Печальный) конец. >>> жаркое([1, 2, 3]) Ошибка типа: объект типа не является уткой! Код классный, но что, если я решу зажарить испанскую или французскую утку? Итак, можно двумя разными способами:

класс Пато (Утка): защита шарлатан(сам): return "¡Куа, куа, куа!" класс Канард: # Здесь намеренно не используется наследование! защита шарлатан(сам): вернуть «Монета-монета!» Это можно использовать как:

>>> жаркое(Пато()) > сказала утка перед тем, как ее зажарить - (Печальный) конец. >>> жаркое(Утка) > сказала утка перед тем, как ее зажарить - (Печальный) конец. Все выглядит хорошо. Однако я хочу приложить дополнительные усилия и добавить в свою функцию подсказки типов. И тут возникает вопрос: существует ли «правильный» способ сделать это? Если я просто изменю функцию на defoast(obj: Duck), при вызове roast(Canard()) моя IDE (PyCharm) предупредит меня:

Ожидал тип «Утка», вместо этого получил «Утка».

что заставляет меня поверить, что это неправильный способ добавления типизации в функцию. Что мне делать вместо этого?

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