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

如何在Python中阻止无抽象方法的抽象基类实例化?

如何让无抽象方法的ABC类被mypy禁止直接实例化?

你目前通过强制子类实现__str__的方式达成需求,但有两种更优的方案可以选择:

方案1:手动标记抽象类属性

直接在抽象基类中设置__abstractmethods__为非空的冻结集合,不需要额外定义抽象方法。Python运行时和mypy都会将这类视为抽象类,禁止实例化;而子类继承后,只要没有未实现的抽象方法,这个集合会被自动清空,子类可以正常实例化。

from abc import ABC
from attrs import frozen

class Abstract(ABC):
    # 随便填一个不存在的方法名,标记类为抽象
    __abstractmethods__ = frozenset({"_abstract_marker"})

    def do_something(self) -> int:
        return 777

@frozen
class Concrete1(Abstract):
    name: str
    some_field: float

@frozen
class Concrete2(Abstract):
    name: int
    some_field: str

# mypy会报错:Cannot instantiate abstract class "Abstract" with abstract attribute "_abstract_marker"
# Python运行时也会抛出TypeError
a = Abstract()

方案2:复用attrs自动生成的方法作为抽象方法

利用attrs为冻结类自动生成的方法(比如__eq__、__hash__),将其标记为抽象方法。因为attrs会自动给子类实现这些方法,所以子类不需要手动编写代码,同时抽象基类会被禁止实例化。

from abc import ABC, abstractmethod
from attrs import frozen

class Abstract(ABC):
    def do_something(self) -> int:
        return 777

    @abstractmethod
    def __eq__(self, other: object) -> bool:
        ...

@frozen
class Concrete1(Abstract):
    name: str
    some_field: float

@frozen
class Concrete2(Abstract):
    name: int
    some_field: str

# mypy报错:Cannot instantiate abstract class "Abstract" with abstract method "__eq__"
a = Abstract()

方案对比

  • 方案1更通用,不依赖attrs或其他库,适合所有继承ABC的场景。
  • 方案2更贴合你的使用场景,无需额外的标记字段,但如果子类不使用attrs,就需要手动实现对应的抽象方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:27:24