from typing import get_type_hints
def strict_types(f):
def type_checker(*args, **kwargs):
hints = get_type_hints(f)
all_args = kwargs.copy()
all_args.update(dict(zip(f.__code__.co_varnames, args)))
for key in all_args:
if key in hints:
if type(all_args[key]) != hints[key]:
raise Exception('Type of {} is {} and not {}'.format(key, type(all_args[key]), hints[key]))
return f(*args, **kwargs)
return type_checker
在定义这样的函数时
@strict_types
def concatenate_with_spam(text: str) -> str:
return text + 'spam'
如果传递给你的函数的参数类型错误,它会引发异常。
Traceback (most recent call last):
File "strict_types.py", line 23, in <module>
concatenate_with_spam(1)
File "strict_types.py", line 13, in type_checker
raise Exception('Type of {} is {} and not {}'.format(key, type(all_args[key]), hints[key]))
Exception: Type of text is <class 'int'> and not <class 'str'>
def type_checker(f):
"""
A decorator that verifies if the arguments of a function match the specified type.
@param f: the function
@return:
"""
def checker(*args, **kwargs):
hints = get_type_hints(f)
all_args = kwargs.copy()
all_args.update(dict(zip(f.__code__.co_varnames, args)))
# Check the args type
for arg_name, arg_value in all_args.items():
if arg_name in hints:
expected_type = hints[arg_name]
# If Union get values
if hasattr(expected_type, "__origin__") and expected_type.__origin__ == typing.Union:
expected_type = expected_type.__args__
msg = f"The `{arg_name}` parameter in `{f.__name__}` function should be an {expected_type} type. " \
f"A {type(arg_value)} type was passed instead."
assert isinstance(arg_value, expected_type), msg
output = f(*args, **kwargs)
# Check the output type if specified
output_type = hints.get('return', None)
if output_type:
msg = f"The `{f.__name__}` function should return a {output_type}, " \
f"but it's returning a {type(output)} instead. " \
"Please ensure that the return type matches the expected type."
assert isinstance(output, output_type), msg
return output
return checker
5条答案
按热度按时间hivapdat1#
从Python 3.4开始,你可以为函数或方法添加类型注解:
然而这些类型并不是强制的-你仍然可以用一个非整数的值来调用函数。
此外,Python基于鸭子类型的思想,所以有时候你可能想要接受各种类型,比如
int
和float
。des4xlb02#
Python使用Duck typing,这意味着你不应该根据对象的类型来区分它们,而是根据它们的属性和函数来区分它们。这具有许多优点,这些优点超出了本答案的范围。
如果你想给你的函数添加文档,你应该使用一个docstring
type hints
如果你真的需要检查给你的参数,你可以执行
hasattr()
来检查参数提供的属性和函数。在大多数情况下(包括这一个)只是不检查类型是更好的yfwxisqw3#
如果要使用语法
@SimeonVisser提到过,你有python3.5,你可以使用我写的装饰器
在定义这样的函数时
如果传递给你的函数的参数类型错误,它会引发异常。
虽然我还没有实现一种方法来检查你返回的类型,如果你也想检查它,这个解决方案不适合你。
vybvopom4#
下面是@ilya-peterov的函数的一个稍微修改的版本,包括检查函数返回值的类型:
mzmfm0qo5#