Python类别名创建:保留独立文档且双向通过isinstance检查
实现互相兼容的类别名并保留独立文档字符串
要满足原类与别名类实例互相通过isinstance检查,同时各自保留独立文档字符串,且不修改实例的__class__属性,有两种可行方案:
方案一:基于元类的自动关联实现
通过自定义元类,自动处理两个类的实例检查逻辑,并同步类的方法属性,避免重复代码:
from abc import ABC class ParentClass(ABC): """Abstract base class""" class MutualInstanceCheckMeta(type): def __new__(cls, name, bases, attrs): new_cls = super().__new__(cls, name, bases, attrs) # 处理别名关联逻辑 if 'alias_for' in attrs: original_cls = attrs['alias_for'] # 更新原类的实例检查方法,纳入别名类实例 original_check = original_cls.__instancecheck__ def updated_original_check(self, instance): return original_check(self, instance) or isinstance(instance, new_cls) original_cls.__instancecheck__ = updated_original_check # 更新别名类的实例检查方法,纳入原类实例 alias_check = new_cls.__instancecheck__ def updated_alias_check(self, instance): return alias_check(self, instance) or isinstance(instance, original_cls) new_cls.__instancecheck__ = updated_alias_check # 同步原类的方法与属性(排除文档字符串等标识属性) for attr_name, attr_val in original_cls.__dict__.items(): if attr_name not in attrs and attr_name not in ('__doc__', '__module__', '__qualname__'): setattr(new_cls, attr_name, attr_val) return new_cls class OGClass(ParentClass, metaclass=MutualInstanceCheckMeta): """OGClass docs""" def __init__(self): self.property1 = "property1" class AliasClass(ParentClass, metaclass=MutualInstanceCheckMeta): """other doc""" alias_for = OGClass # 验证逻辑 og_obj = OGClass() ali_obj = AliasClass() assert isinstance(og_obj, OGClass) # True assert isinstance(ali_obj, OGClass) # True assert isinstance(ali_obj, AliasClass)# True assert isinstance(og_obj, AliasClass) # True assert OGClass.__doc__ == """OGClass docs""" # True assert AliasClass.__doc__ == """other doc""" # True
方案说明
- 元类
MutualInstanceCheckMeta在创建带有alias_for属性的类时,自动关联指定的原类。 - 动态修改两个类的
__instancecheck__方法,使它们互相识别对方的实例。 - 自动同步原类的方法和属性到别名类,确保两个类的实例行为一致,同时保留各自独立的文档字符串。
方案二:手动修改实例检查方法
对于结构简单的类,可直接手动替换两个类的__instancecheck__方法,无需依赖元类:
from abc import ABC class ParentClass(ABC): """Abstract base class""" class OGClass(ParentClass): """OGClass docs""" def __init__(self): self.property1 = "property1" class AliasClass(ParentClass): """other doc""" def __init__(self): self.property1 = "property1" # 手动更新OGClass的实例检查逻辑 original_og_check = OGClass.__instancecheck__ def og_instance_check(self, instance): return original_og_check(self, instance) or isinstance(instance, AliasClass) OGClass.__instancecheck__ = og_instance_check # 手动更新AliasClass的实例检查逻辑 original_alias_check = AliasClass.__instancecheck__ def alias_instance_check(self, instance): return original_alias_check(self, instance) or isinstance(instance, OGClass) AliasClass.__instancecheck__ = alias_instance_check # 验证逻辑 og_obj = OGClass() ali_obj = AliasClass() assert isinstance(og_obj, OGClass) # True assert isinstance(ali_obj, OGClass) # True assert isinstance(ali_obj, AliasClass)# True assert isinstance(og_obj, AliasClass) # True assert OGClass.__doc__ == """OGClass docs""" # True assert AliasClass.__doc__ == """other doc""" # True
方案说明
- 两个类完全独立定义,各自实现相同的业务逻辑(可将公共逻辑抽为Mixin类进一步优化)。
- 手动替换
__instancecheck__方法,扩展实例检查范围,纳入对方类的实例。 - 实现简单直观,无需理解元类机制,适合小型类场景。
内容的提问来源于stack exchange,提问作者Korbinian Kottmann
相关产品推荐
相关产品推荐

