Я часто нахожу, что я пишу выражения с несколькими операторами, чтобы проверять типы переменных во время выполнения. Например, предположим, что я хотел, чтобы убедиться, что конкретный вход список объектов Foo, я мог бы написать следующее выражение:Есть ли способ определить, является ли объект «экземпляром» выражения стиля pep484 во время выполнения?
assert(_isinstance(x, list) and all(_isinstance(y, Foo) for y in x))
я лучше быть в состоянии написать что-то вроде:
# pseudocode
_assert(isinstance(x, typing.List[Foo]))
Другими словами, я хочу задать x список экземпляров Foo.
Если это может быть сделано для работы, это было бы лучше, потому что синтаксис Pep484 - отличный способ кратко указать типы вложенных структур. Конечно, мы все знаем, что это не так, как работает встроенная функция Python isinstance ... но мне просто снится на мгновение:
Мы все знакомы с функцией isnstance, которая возвращает True, если внешний тип структуры является экземпляром класса:
# real python:
isinstance(["a", "b", "c"], list) => True
Но предположим, что я хочу сделать более глубокие проверки: Я хотел бы сделать что-то вроде:
# pseudocode:
import typing
_isinstance("x", str) => True
_isinstance(["a", "b", "c"], typing.List[str]) => True
_isinstance(["a", "b", "c"], typing.List[float]) => False
_isinstance([{"x":3}], typing.List[typing.Map[str,int]]) => True
Так идея заключается в том, что функция вернет True, если 1-й аргумент полностью соответствует стилю стиля Pep484 второго аргумента.
Конечно, некоторые из вас укажут, что явная статическая проверка и проверка времени выполнения противоречат духу «утиной печати». Это правда, но не полезно. Иногда вы действительно хотите проверить структуру ввода. По мере того, как проекты становятся все больше, вы иногда хотите узнать наверняка, с какими типами вы сталкиваетесь, и в другое время вам нужна гибкость, которую дает вам утка.
Итак, вот мой вопрос: кто-нибудь видел способ сравнить выражения стиля Pep484 с типами? Если для этого уже есть библиотека или функция, я бы предпочел не изобретать колесо. Возможно, у библиотеки ввода есть способ сделать это. Назовите меня, пожалуйста!
Вы использовали 'isinstance' назад во всех своих гипотетических примерах. Не то, чтобы это сработало, если бы вы перевернули его. 'isinstance' не делает то, что вы хотите. – ShadowRanger
Это было обратное в одном примере - я исправил это, спасибо! –
Вы только что сделали это назад в другом примере. Прототипом является 'isinstance (obj, type_or_tuple_of_types)', а не 'isinstance (type_or_tuple_of_types, obj)'. Тестирование, если 'x' имеет тип или подтип' list', является 'isinstance (x, list)', а не 'isinstance (list, x)'. – ShadowRanger