如何使用另一个函数的返回类型来注释Python函数?

11

我正在寻找C++中的decltype的某种类比。我的目标是:

def f(a: int) -> List[Tuple(int, float)]
def g(a: List[int]) -> List[decltype(f)]

因此,这个想法是使用另一个函数的类型注释。我找到的解决方案看起来有些笨拙:

def g(a: List[int])->f.__annotations__['return']

基本上,问题是是否存在像 decltype 这样的东西(也许它应该被称为“返回类型”),或者在以后的版本中是否有计划。我还编写了一个小函数,说明了可能使用此功能的情况:

def return_type(f: Callable):
   try:
       return get_type_hints(f)['return']
   except(KeyError, AttributeError):
       return Any
def g() -> return_type(f):

UPD根据Jim Fasarakis-Hilliard的建议,我们也可以使用get_type_hints替代annotations


你的意思是像这样吗:def decltype(function): return function.__annotations__['return']? :) - cowbert
@cowbert 是的,我刚刚添加了一个类似的例子 :) 实际上,我很困惑为什么没有针对这种情况的函数,我想知道这种态度是否有问题。 - ig-melnyk
1个回答

10

目前还没有类似的东西,也没有在类型追踪器上发现相关计划。你可以创建一个问题来了解这个功能的受欢迎程度。

目前你的方法可以实现(即分配类型),我唯一想做的改变是使用typing中的get_type_hints而不是直接获取__annotations__属性。再加上.get(因为它返回一个字典),也可以使这个过程更短:

def return_type(f):
    return get_type_hints(f).get('return', Any)

def g() -> return_type(f):

如果你愿意,可以将其从函数中删除并在单行中使用。

如果存在随机对象被提供给return_type的可能性,则需要捕获它引发的TypeError并返回默认值Any

def return_type(f):
    try:
        return get_type_hints(f).get('return', Any)
    except TypeError:
        return Any

当然,由于这种方式动态分配类型,你不能指望静态类型检查器捕获它,需要使用静态提示来实现。

谢谢提到get_type_hints!我会把这个加到问题文本中。 - ig-melnyk
请注意,使用get_type_hints,如果您真的想要它成为一行代码,那么这确实变成了一个一行代码的问题 :-) - Dimitris Fasarakis Hilliard
也许我们仍应该检查 AttributeError,以防它不是可调用的? - ig-melnyk
@ig-melnyk 当然,如果除了函数(在3.5中)和函数、类、模块(在3.6+中)之外的其他东西可能被传递进来,你就需要这样做了。我不知道那是情况。 - Dimitris Fasarakis Hilliard
2
这似乎与当前的静态分析工具不兼容。 - user2357112

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接