You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过类型检查确保Python函数遵循同一接口(使用mypy)

更Pythonic的方式让多个函数遵循同一类型接口(基于mypy)

方法1:直接为函数添加类型注解(最简洁)

不需要额外的中间变量,直接在函数定义时明确参数和返回值类型,mypy会自动验证签名是否匹配你定义的接口:

from typing import Callable

# 定义接口类型
BinaryFunction = Callable[[float, float], float]

# 直接给函数添加类型注解
def plus(a: float, b: float) -> float:
    return a + b

def minus(a: float, b: float) -> float:
    return a - b

这种写法完全符合Python风格,没有冗余代码。当你需要将这些函数传递给标注了BinaryFunction类型的参数时,mypy会自动校验兼容性:

def calculate(op: BinaryFunction, x: float, y: float) -> float:
    return op(x, y)

# mypy会正常通过校验
calculate(plus, 1.5, 2.5)
calculate(minus, 3.0, 1.0)

方法2:使用Protocol定义接口(更灵活,适合复杂场景)

如果需要更接近"接口"的语义(比如未来可能扩展约束),可以用Python 3.8+的Protocol(3.8以下可通过typing_extensions导入),它比Callable更灵活,支持定义复杂调用签名或附加属性:

from typing import Protocol

# 定义协议(接口)
class BinaryFunction(Protocol):
    def __call__(self, a: float, b: float) -> float:
        ...

# 实现函数无需显式继承,mypy会自动校验是否符合协议
def plus(a: float, b: float) -> float:
    return a + b

def minus(a: float, b: float) -> float:
    return a - b

# 使用接口类型
def apply_operation(op: BinaryFunction, x: float, y: float) -> float:
    return op(x, y)

这种方式语义更清晰,后续扩展接口(比如要求函数具备某个属性)时,只需修改BinaryFunction协议即可,无需改动所有函数定义。

为什么原写法不够Pythonic?

你之前用checkedPlus: BinaryFunction = plus的方式,是通过额外变量触发类型校验,但这个变量在运行时没有实际用途,属于冗余代码。上面两种方法遵循了Python"显式优于隐式"的原则,直接在函数定义或接口层面明确约束,代码更简洁易懂。

内容的提问来源于stack exchange,提问作者chichak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:05:06