Created
January 11, 2019 13:02
-
-
Save Aloxaf/a7a69874000a8e162cedb5feee3a27c4 to your computer and use it in GitHub Desktop.
借助 Type Hint 进行运行时类型检查的 Python 装饰器
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://aboutsimon.com/blog/2018/04/04/Python3-Type-Checking-And-Data-Validation-With-Type-Hints.html | |
from functools import wraps | |
from inspect import getfullargspec | |
from typing import get_type_hints | |
def validate_input(hints, **kwargs): | |
# iterate all type hints | |
for attr_name, attr_type in hints.items(): | |
if attr_name == 'return': | |
continue | |
if not isinstance(kwargs[attr_name], attr_type): | |
raise TypeError(f'Argument {attr_name} is not of type {attr_type}') | |
def type_check(decorator): | |
@wraps(decorator) | |
def wrapped_decorator(*args, **kwargs): | |
# translate *args into **kwargs | |
func_args = getfullargspec(decorator)[0] | |
kwargs.update(dict(zip(func_args, args))) | |
hints = get_type_hints(decorator) | |
validate_input(hints, **kwargs) | |
ret = decorator(**kwargs) | |
if not isinstance(ret, hints['return']): | |
raise TypeError(f'Return value is not of type {hints["return"]}') | |
return ret | |
return wrapped_decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment