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

如何用mypy为无法导入的外部库创建伪类型实现类型检查?

外部不可用SDK的类型检查解决方案

针对你遇到的嵌入式SDK无法在开发环境正常运行、无类型注解,但需要为调用代码添加类型检查的问题,以下是几种可行方案:

1. 使用类型存根文件(.pyi)

创建与SDK目录结构完全匹配的类型存根文件(后缀为.pyi),仅定义你需要调用的类、方法的类型签名,无需实现具体逻辑。

比如SDK模块路径为embedded_sdk.device,则创建embedded_sdk/device.pyi文件:

# embedded_sdk/device.pyi
class Sensor:
    def __init__(self, pin: int, baud_rate: int = 9600) -> None: ...
    def read_data(self) -> float: ...
  • 类型检查工具(如mypy)会优先读取存根文件进行类型校验,运行时不会加载存根
  • 当SDK可用时,若真实代码有类型注解会覆盖存根,无注解则存根依然生效

2. 利用typing.TYPE_CHECKING做条件导入

TYPE_CHECKING是一个仅在类型检查阶段为True的常量,可借此实现"检查时用真实/伪类型,运行时跳过导入"的逻辑:

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    # 类型检查阶段尝试导入真实类型,失败则定义伪类型
    try:
        from embedded_sdk.device import Sensor
    except ImportError:
        class Sensor:
            def __init__(self, pin: int, baud_rate: int = 9600) -> None: ...
            def read_data(self) -> float: ...
else:
    # 运行时用Any避免导入报错
    Sensor = Any
  • 本地开发时,类型检查工具会基于定义的伪类型校验参数传递
  • SDK可用时,自动使用真实类型进行更精准的检查

3. 用Protocol定义接口(推荐)

如果只关注接口兼容性而非具体类型,可通过Protocol定义你需要的方法签名,让代码遵循该接口:

from typing import Protocol, TYPE_CHECKING, cast

# 定义SDK类需要遵循的接口
class SensorProtocol(Protocol):
    def __init__(self, pin: int, baud_rate: int = 9600) -> None: ...
    def read_data(self) -> float: ...

# 类型检查阶段用Protocol,运行时动态获取真实类型或占位
if TYPE_CHECKING:
    SensorType = SensorProtocol
else:
    try:
        from embedded_sdk.device import Sensor as SensorType
    except ImportError:
        SensorType = object

# 调用代码标注为Protocol类型,确保参数和返回值符合要求
def process_sensor_data(sensor: SensorType) -> float:
    raw_data = sensor.read_data()
    return raw_data * 1.2

# 实例化逻辑:SDK可用则用真实类,否则用本地模拟类
try:
    sensor = SensorType(pin=3)
except:
    class MockSensor:
        def __init__(self, pin: int, baud_rate: int = 9600) -> None:
            self.pin = pin
        def read_data(self) -> float:
            return 22.5
    # 用cast告诉类型检查工具模拟类符合Protocol
    sensor = cast(SensorProtocol, MockSensor(pin=3))
  • 无论SDK是否可用,类型检查都能验证代码是否符合接口定义
  • 模拟类只需实现接口中的方法,无需复刻SDK全部功能

注意事项

  • 伪类型、存根或Protocol只需定义你实际用到的方法和属性,无需完整复刻SDK
  • 若SDK可用时需要精准校验,确保存根/Protocol的定义与真实SDK接口一致
  • 运行时需做好异常捕获,避免因SDK不可用导致程序崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:08:14