问题描述
我很确定,以前有人问过这个问题,但我不知道要搜索什么..
例如(这个例子完全没有意义——只是为了演示)
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 有关,但我不知道如何使用它们来创建“函数模板”。
解决方法
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)