Простой ответ:
Просто введите все аргументы, например:
def type_check(value, annotation):
if isinstance(annotation, type):
return isinstance(value, annotation)
elif annotation == typing.T or annotation == typing.Any:
return True
elif isinstance(annotation, typing._GenericAlias):
if annotation.__origin__ == list:
if not isinstance(value, list):
return False
inner_annotation = annotation.__args__[0]
return all(type_check(val, inner_annotation) for val in value)
Пример
>>> type_check(5, int)
True
>>> type_check([1, 2, 3], typing.List[int])
True
>>> type_check([1, 2, 3], typing.List[float])
False
Который вы можете просто использовать в своем декораторе. Его можно улучшить для обработки Dict, Tuple и других распространенных типов.
Однако это просто игрушечный пример, если вы хотите выполнить надежную динамическую проверку типов c, вам придется обрабатывать Generator
, Callable
, Iterator
et c ... что не только довольно сложно, но и в некоторых случаях совершенно невозможно (например, итераторы не могут быть проверены без повторения).
Посмотрите в проекте enforce , что и есть: проверка типов python Dynami c с использованием декораторов. Исходный код модуля typing
тоже очень интересно читать, но он действительно расширяет пределы возможностей динамической c интроспекции.
Надеюсь, это поможет;)