如何在 Python 中对函数(即“函数模板”)进行“泛型类型提示”?

Posted

技术标签:

【中文标题】如何在 Python 中对函数(即“函数模板”)进行“泛型类型提示”?【英文标题】:How to do 'generic type hinting' of functions (i.e 'function templates') in Python? 【发布时间】:2021-07-11 06:55:01 【问题描述】:

我很确定,以前有人问过这个问题,但我不知道要搜索什么..

我想键入提示“通用”函数(如 C++ 中的函数模板)

例如(这个例子完全没有意义——只是为了演示)

def foo(fn: Callable[Any, Any], args: Any) -> Any:
    return fn(args)

我想在我有完整类型信息的上下文中使用这个函数,所以我希望我可以摆脱任何Any

def bar() -> int:
    func: Callable[[str], int] = lambda arg: len(arg)
    return foo(func, "Hurz")

一种方法当然是将foo 显式转换为(Callable[[str], int], str) -> int,但我正在寻找通用方法。

我猜我正在寻找的内容与 generics 有关,但我不知道如何使用它们来创建“函数模板”。

【问题讨论】:

(fn: Callable[[A], R], arg: A) -> R? AR 是什么? foo 可能是包的一部分并且不知道它正在使用的类型.. ...它们是泛型类型,TypeVars。 好的,TypeVar 是我应该寻找的(而不是Generics)-谢谢。如果你想把它变成一个答案,我会接受它 【参考方案1】:

Python typing 有两个部分来完成通常称为 generic programming 或 parametric polymorphism 或简称为“泛型”或“模板”的工作:

typing.TypeVar 定义一个通用占位符,例如T,以及 typing.Generic 定义一个通用类型,例如List

两者一起形成完全可参数化的类型,例如List[T]。由于函数是内置的,def 关键字自然定义了泛型类型——只需要TypeVar

只需为签名中所需的每个类型占位符定义一个TypeVar

from typing import TypeVar, Callable

T = TypeVar('T')
R = TypeVar('R')

def foo(fn: Callable[[T], R], args: T) -> R:
    return fn(args)

【讨论】:

以上是关于如何在 Python 中对函数(即“函数模板”)进行“泛型类型提示”?的主要内容,如果未能解决你的问题,请参考以下文章

C++学习_模板和泛型

在python中对元祖进行排序

零值初始化&字符串常数作为函数模板参数

在python中对自定义类执行集合操作

如何在python中对信号应用过滤器

如何在 python 中对装饰器工厂输入进行单元测试