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

如何实现可与@abstractmethod链式使用的@classproperty装饰器

可与@abstractmethod链式使用的classproperty实现方案

核心修改点

  • 修正__isabstractmethod__属性实现:透传被装饰方法的__isabstractmethod__标记,让ABC元类可以正确识别抽象类属性,原生触发实例化时的类型校验
  • 新增访问校验逻辑:在__get__方法中判断如果是未实现的抽象类属性,直接抛出符合原生@abstractmethod格式的TypeError
  • 装饰器顺序要求:@classproperty必须放在@abstractmethod外层,保证抽象标记可以正确透传

完整实现代码

from abc import ABC, abstractmethod

class classproperty(property):
    """
    类属性装饰器,支持与@abstractmethod链式使用
    """
    def __init__(self, fget, *args, **kwargs):
        super().__init__(fget, *args, **kwargs)
        self.__doc__ = fget.__doc__
        # 透传被装饰方法的抽象方法标记
        self.__isabstractmethod__ = getattr(fget, "__isabstractmethod__", False)

    def __get__(self, instance, owner):
        # 抽象属性被访问时直接抛出符合要求的TypeError
        if self.__isabstractmethod__:
            raise TypeError(
                f"Can't instantiate abstract class {owner.__name__} with abstract methods {self.fget.__name__}"
            )
        return self.fget(owner)


class MyAbstractClass(ABC):
    @classproperty
    def non_abstract_class_property(self) -> str:
        """普通类属性示例,功能正常"""
        return "value 1"

    @classproperty
    @abstractmethod
    def abstract_class_property(self) -> str:
        """抽象类属性示例,子类必须实现"""
        pass


class ConcreteNotImplemented(MyAbstractClass):
    """未实现抽象类属性的子类,会触发校验错误"""
    pass


# 以下是测试代码,运行会依次触发对应错误
print("MyAbstractBaseClass TESTS")
print(MyAbstractClass.non_abstract_class_property)
print(MyAbstractClass.abstract_class_property)  # 触发case1错误
print()

print("ConcreteNotImplemented TESTS")
print(ConcreteNotImplemented.non_abstract_class_property)
print(ConcreteNotImplemented().abstract_class_property)  # 触发case2错误
print(ConcreteNotImplemented.abstract_class_property)  # 触发case3错误
print(ConcreteNotImplemented())  # 实例化时原生触发抽象类错误

运行效果说明

代码运行后会依次触发符合要求的错误:

  1. 访问MyAbstractClass.abstract_class_property时抛出TypeError: Can't instantiate abstract class MyAbstractClass with abstract methods abstract_class_property,符合case1要求
  2. 实例化ConcreteNotImplemented时ABC元类自动抛出同格式TypeError,符合case2要求
  3. 访问ConcreteNotImplemented.abstract_class_property时抛出同格式TypeError,符合case3要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:42:01