遍历类实例列表调用函数时MyPy报'object无my_function'错误求助
解决MyPy报错"object has no attribute 'my_function'"的方法
MyPy报错是因为它默认把未标注类型的实例列表推断为list[object],而object类并没有my_function方法。虽然Python动态类型特性让代码能正常运行,但要通过MyPy的类型检查,需要明确声明类的共同接口或列表元素类型,以下是几种可行方案:
1. 使用抽象基类(ABC)定义统一接口
让所有包含my_function的类继承一个抽象基类,基类中声明该方法的抽象定义,然后将列表标注为这个基类的列表:
from abc import ABC, abstractmethod class MyBase(ABC): @abstractmethod def my_function(self) -> None: pass class MyClass1(MyBase): def my_function(self) -> None: print("Class 1 implementation") class MyClass2(MyBase): def my_function(self) -> None: print("Class 2 implementation") # 明确标注列表类型为MyBase的实例列表 instances: list[MyBase] = [MyClass1(), MyClass2()] for instance in instances: instance.my_function()
2. 使用Protocol实现结构子类型(Python 3.8+)
如果不想让类继承共同基类,可以用Protocol定义一个"接口契约",只要类实现了my_function方法,就会被MyPy识别为符合该Protocol的类型:
from typing import Protocol class HasMyFunction(Protocol): def my_function(self) -> None: ... class MyClass1: def my_function(self) -> None: print("Class 1 implementation") class MyClass2: def my_function(self) -> None: print("Class 2 implementation") # 标注列表类型为HasMyFunction的实例列表 instances: list[HasMyFunction] = [MyClass1(), MyClass2()] for instance in instances: instance.my_function()
3. 直接标注列表的联合类型
如果涉及的类数量不多,可以直接将列表元素类型标注为多个类的联合类型:
class MyClass1: def my_function(self) -> None: print("Class 1 implementation") class MyClass2: def my_function(self) -> None: print("Class 2 implementation") # 明确标注列表元素为MyClass1或MyClass2的实例 instances: list[MyClass1 | MyClass2] = [MyClass1(), MyClass2()] for instance in instances: instance.my_function()
以上三种方法都能让MyPy正确识别列表中实例的类型,消除类型检查错误。
内容的提问来源于stack exchange,提问作者Kulu
相关产品推荐
相关产品推荐

