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

如何解决python-attrs构造时的unexpected keyword argument问题并让mypy校验通过

问题原因

你遇到的类型报错是静态检查工具的特性导致的:mypy/pyright只能识别类的静态定义,感知不到你在运行时通过attr.s(these=...)给第三方类A动态添加的attrs字段与初始化逻辑。因此它处理子类B的继承关系时,不会把a识别为B的合法构造参数,而运行时因为动态修改已经生效,所以代码可以正常执行。

可行解决方法

下面几种方案都可以解决类型报错,你可以根据自己的场景选择:

方案1:子类显式声明继承字段(最简便)

attrs 20.1.0以上版本支持inherited=True参数,你可以在子类B中显式声明继承自父类的字段,不需要重复定义字段逻辑,就能让类型检查器识别该参数:

import attr

class A:
    def __init__(self, a: int):
        self.a = a

# 注意这里原有代码的type=str和A的原生定义冲突,要改为int保持类型一致
attr.s(these={
    "a": attr.ib(type=int)
}, init=True)(A)

@attr.s(kw_only=True)
class B(A):
    # 显式声明继承的a字段,类型检查器会自动识别为构造参数
    a: int = attr.ib(inherited=True)
    b: int = attr.ib()

if __name__ == "__main__":
    a = A(1)
    b = B(a=1, b=2)
    print(a)
    print(b)

修改后mypy/pyright都能正常识别B(a=1, b=2)的写法。

方案2:为第三方类A添加类型存根

如果你不想在每个子类中都显式声明继承字段,可以给第三方类A单独加类型存根文件,让静态检查器直接识别A是attrs类:

  1. 在你的项目根目录新建stubs文件夹,在里面创建和第三方库路径对应的文件结构,比如A类在thirdparty.module里,就新建stubs/thirdparty/module.pyi
  2. 存根文件内容如下:
import attr

@attr.s
class A:
    a: int = attr.ib()
  1. 在mypy配置文件mypy.ini中添加存根路径配置:
[mypy]
python_version = 3.8
mypy_path = stubs

配置完成后静态检查器会直接读取存根的定义,子类B不需要加额外代码就能正常识别a参数。

方案3:关闭单条语句的类型检查(临时妥协方案)

如果只是临时解决不想改代码结构,可以在报错的行加类型忽略注释,不推荐长期使用:

b = B(a=1, b=2) # type: ignore

内容的提问来源于stack exchange,提问作者Nico W.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:06:03