如何检查被@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
相关产品推荐
相关产品推荐

