Python中如何为参数中的函数/方法添加正确的类型注解
Python函数/方法类型标注实现方法
标注函数、方法这类可调用对象的类型,核心使用Callable类型注解,根据场景可以选择基础写法或者泛型写法适配更灵活的需求。
基础固定签名场景
如果被传入的函数签名是固定的,直接使用Callable[[参数类型列表], 返回值类型]格式标注即可:
- Python 3.9+ 可以直接从
collections.abc导入Callable - 更低版本从
typing模块导入Callable即可
针对你示例里固定接收两个int返回int的add函数,写法如下:
from typing import Callable def add(a: int, b: int) -> int: return a + b def run_with_notify(func: Callable[[int, int], int], *args: int) -> None: print("Start!") print(func(*args)) print("End!") run_with_notify(add, 2, 3)
如果不需要严格校验参数列表,只需要标注是可调用对象,也可以简写为Callable[..., 返回值类型],三个点代表匹配任意参数列表。
灵活泛型场景(推荐包装函数使用)
如果你写的是类似示例里的通用包装函数,需要兼容任意签名的传入函数,同时让IDE保留参数校验、返回值类型推导能力,就需要搭配ParamSpec和TypeVar实现泛型标注:
- Python 3.10+ 可直接从
typing导入这两个类型 - 3.9及更早版本需要安装
typing_extensions包后从该模块导入
完整写法示例:
from typing import Callable, TypeVar, ParamSpec # 定义泛型占位符:P匹配传入函数的参数签名,R匹配传入函数的返回值类型 P = ParamSpec("P") R = TypeVar("R") def add(a: int, b: int) -> int: return a + b def run_with_notify(func: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R: print("Start!") res = func(*args, **kwargs) print(res) print("End!") return res # IDE会自动识别参数规则:传入add时,后续参数必须符合add的入参要求,同时推导返回值为int类型 run_with_notify(add, 2, 3)
补充说明
- 如果完全不需要校验可调用对象的签名和返回值,直接标注
Callable即可,等价于Callable[..., Any] - 标注实例方法、类方法、静态方法的逻辑和普通函数完全一致,不需要额外处理self/cls参数(这类参数是调用时自动传入的,标注时只需要关注手动传入的参数列表即可)
- 标注无返回值的可调用对象时,返回值位置填
None即可,比如Callable[[str], None]代表接收一个字符串参数、无返回值的函数。
内容的提问来源于stack exchange,提问作者FogyX
相关产品推荐
相关产品推荐

