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

如何告知mypy指定对象具备特定属性?

解决方案

方案1:Protocol + TypeGuard 组合(推荐)

无需修改原有类继承结构,通过静态类型约定实现自动类型窄化,维护成本最低。

  1. 先定义Protocol描述目标属性结构:
from typing import Protocol, TypeGuard

class PositionedWidget(Protocol):
    posx: float
    posy: float
  1. 实现类型守卫函数封装判断逻辑:
def has_position_attrs(obj: Widget) -> TypeGuard[PositionedWidget]:
    return hasattr(obj, "posx") and hasattr(obj, "posy")
  1. 过滤时使用该函数做判断,mypy会自动将符合条件的实例识别为PositionedWidget类型,直接访问属性不会报错:
for widget in all_widgets:
    if has_position_attrs(widget):
        # 此处mypy已确认widget包含posx、posy属性
        print(widget.posx, widget.posy)

方案2:cast显式类型转换

适合临时、少量场景使用,比# type: ignore可控性更高,仅作用于当前转换的变量:

from typing import cast, Union

for widget in all_widgets:
    if hasattr(widget, "posx") and hasattr(widget, "posy"):
        # 可直接填所有带属性的子类联合,也可以用之前定义的PositionedWidget Protocol
        positioned_widget = cast(Union[Rectangle, Button], widget)
        print(positioned_widget.posx, positioned_widget.posy)

方案3:多类型isinstance判断

仅适合带属性的子类数量少且固定的场景,无需引入额外注解工具:

for widget in all_widgets:
    if isinstance(widget, (Rectangle, Button)):
        # mypy会自动窄化类型为Rectangle/Button的联合,可正常访问属性
        print(widget.posx, widget.posy)

内容的提问来源于stack exchange,提问作者Jean-Francois T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:27:02