以下
try_parse
方法将 T
类型的值和一系列输入类型为 T
的函数作为输入。这些函数不一定必须具有相同的输出类型,例如,它可以是 int
、float
、MyCustomClass
等。我如何在这段代码中适当地注释函数类型?
T = TypeVar("T")
U = TypeVar("U")
def try_parse(value: T, *parse_functions: Callable[[T], U]) -> U:
for parse_function in parse_functions:
try:
return parse_function(value)
except ValueError:
pass
raise ValueError(f"Cannot parse {value} with any of {parse_functions}")
注释
try_parse
方法的一种方法(假设您希望保持代码灵活性,但仍然在某种程度上受益于类型检查)是将 parse_functions 输入为可调用序列,其中每个可调用函数采用 T
类型的输入,并且返回类型为 Any
的值。这种方法为了灵活性牺牲了一些类型特异性:
from typing import TypeVar, Callable, Any
T = TypeVar("T")
def try_parse(value: T, *parse_functions: Callable[[T], Any]) -> Any:
for parse_function in parse_functions:
try:
return parse_function(value)
except ValueError:
pass
raise ValueError(f"Cannot parse {value} with any of {parse_functions}")
Any
用于 parse_functions 的返回类型和 try_parse 本身的返回类型,表示该函数可以返回任何类型,这符合您的 parse_functions 可以具有不同输出类型的要求。虽然这种方法通过引入 Any 减少了静态类型检查的好处,但它更准确地反映了 try_parse
函数的动态性质。
如果您在可以保证 parse_functions 中的所有函数都返回相同类型的上下文中工作,或者如果您可以强制执行该约束,则可以坚持使用 U 作为返回类型的原始注释。但是,根据您的描述,似乎使用 Any 更接近您对此功能的意图。