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

如何检查被@classmethod装饰的对象是否绑定@property?

运行时检查classmethod装饰的是否为property

底层实现层面的检查方法

Python 3.3+中,classmethod对象会保留__wrapped__属性,指向被它装饰的原始对象,我们可以通过这个属性获取被包裹的实例并做类型检查:

class A:
    @classmethod
    @property
    def d(cls):
        return 'foo'

# 提取类中的classmethod对象
cls_method = A.__dict__["d"]

# 检查逻辑
if isinstance(cls_method, classmethod):
    wrapped_obj = getattr(cls_method, "__wrapped__", None)
    if isinstance(wrapped_obj, property):
        print("classmethod装饰的是property对象")
    else:
        print("classmethod未装饰property对象")

如果存在多层装饰器嵌套,可使用inspect.unwrap解开装饰器链,直到找到目标类型:

from inspect import unwrap

class A:
    @classmethod
    @property
    def d(cls):
        return 'foo'

cls_method = A.__dict__["d"]
# 解开装饰器链,直到没有__wrapped__属性
unwrapped_obj = unwrap(cls_method, stop=lambda x: not hasattr(x, "__wrapped__"))
if isinstance(unwrapped_obj, property):
    print("符合要求:classmethod最终装饰的是property")

自定义装饰器简化定义与检查

自定义合并classmethod和property功能的装饰器,既简化类定义,也能直接通过类型检查判断:

class classproperty(property):
    def __get__(self, instance, owner=None):
        return super().__get__(owner)

# 使用自定义装饰器定义类属性
class A:
    @classproperty
    def d(cls):
        return 'foo'

# 运行时检查
if isinstance(A.__dict__["d"], classproperty):
    print("这是一个类级别的property")

类型注解层面的约束

通过自定义泛型类型配合静态检查工具(如mypy),提前规避不符合要求的定义:

from typing import TypeVar, Generic, ClassVar

T = TypeVar('T')

class ClassProperty(Generic[T]):
    def __get__(self, instance: None, owner: type) -> T:
        ...

class A:
    # 用ClassProperty注解类属性类型
    d: ClassProperty[str]
    @classmethod
    @property
    def d(cls) -> str:
        return 'foo'

当d的装饰器不符合要求时,mypy会直接抛出类型错误,提前发现问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:01:24