目标:创建一个单调度泛型函数;根据functools文档
我想用my_func()
来计算dtypes:int
或list
,成对。
注意:我已经选择实现类型提示,并为我自己的测试用例提出错误,超出了本文的范围。
对于许多参数数据类型提示;这篇文章使用了许多@my_func.register(...)
装饰器。
代码:
from functools import singledispatch
from typeguard import typechecked
from typing import Union
@singledispatch
@typechecked
def my_func(x, y):
raise NotImplementedError(f'{type(x)} and or {type(y)} are not supported.')
@my_func.register(int)
def my_func(x: int, y: int) -> Union[int, str]:
try:
return round(100 * x / (x + y))
except (ZeroDivisionError, TypeError, AssertionError) as e:
return f'{e}'
@my_func.register(list)
def my_func(x: list, y: list) -> Union[int, str]:
try:
return round(100 * sum(x) / (sum(x) + sum(y)))
except (ZeroDivisionError, TypeError, AssertionError) as e:
return f'{e}'
a = my_func(1, 2)
print(a)
b = my_func([0, 1], [2, 3])
print(b)
(venv) me@ubuntu-pcs:~/PycharmProjects/project$ python3 foo/bar.py
/home/me/miniconda3/envs/venv/lib/python3.9/site-packages/typeguard/__init__.py:1016: UserWarning: no type annotations present -- not typechecking __main__.my_func
warn('no type annotations present -- not typechecking {}'.format(function_name(func)))
Traceback (most recent call last):
File "/home/me/PycharmProjects/project/foo/bar.py", line 22, in <module>
@my_func.register(list)
AttributeError: 'function' object has no attribute 'register'
函数必须唯一命名
感谢@Bijay Regmi指出这一点。
@typechecked
只在@my_func.register
的多态函数之上;不高于@singledispatch
功能。
注意:你仍然调用my_func()
;我只是在测试多态函数。
from functools import singledispatch
from typeguard import typechecked
from typing import Union
@singledispatch
def my_func(x, y):
raise NotImplementedError(f'{type(x)} and or {type(y)} are not supported.')
@my_func.register(int)
@typechecked
def my_func_int(x: int, y: int) -> Union[int, str]:
try:
return round(100 * x / (x + y))
except (ZeroDivisionError, TypeError, AssertionError) as e:
return f'{e}'
@my_func.register(list)
@typechecked
def my_func_list(x: list, y: list) -> Union[int, str]:
try:
return round(100 * sum(x) / (sum(x) + sum(y)))
except (ZeroDivisionError, TypeError, AssertionError) as e:
return f'{e}'
a = my_func_int(1, 2)
print(a)
b = my_func_list([0, 1], [2, 3])
print(b)
(venv) me@ubuntu-pcs:~/PycharmProjects/project$ python3 foo/bar.py
33
17