Python: как использовать подсказки типов в сочетании с `__instancecheck__` ⇐ Python
-
Anonymous
Python: как использовать подсказки типов в сочетании с `__instancecheck__`
Позвольте мне построить мой вопрос шаг за шагом, используя глупый пример: у меня есть функция 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) предупредит меня:
Ожидал тип «Утка», вместо этого получил «Утка».
что заставляет меня поверить, что это неправильный способ добавления типизации в функцию. Что мне делать вместо этого?
Позвольте мне построить мой вопрос шаг за шагом, используя глупый пример: у меня есть функция 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) предупредит меня:
Ожидал тип «Утка», вместо этого получил «Утка».
что заставляет меня поверить, что это неправильный способ добавления типизации в функцию. Что мне делать вместо этого?