Python中继承collections.abc.Set的Enum元类冲突解决方案
解决方案
冲突根源
多继承触发元类冲突的本质是两个基类的元类不存在继承关系:
collections.abc.Set的元类是ABCMetaEnum的元类是EnumMeta
Python多继承规则要求子类的元类必须是所有基类元类的共同子类,因此只需要提前定义同时继承两个元类的混合元类,指定给目标枚举类即可解决冲突。
可运行最小实现
import collections.abc from enum import Enum, EnumMeta from abc import ABCMeta # 兼容两个基类的混合元类 class SetEnumMeta(ABCMeta, EnumMeta): pass class MyClass(collections.abc.Set, Enum, metaclass=SetEnumMeta): AB = {1} CD = {1, 2} def __iter__(self): return iter(self.value) def __contains__(self, key): return key in self.value def __len__(self): return len(self.value)
效果验证
执行以下测试代码可以确认实现完全符合collections.abc.Set的接口要求:
# 集合接口功能测试 print(1 in MyClass.AB) # True print(2 in MyClass.AB) # False print(list(MyClass.CD)) # [1, 2] print(len(MyClass.CD)) # 2 # 抽象基类实例校验 print(isinstance(MyClass.AB, collections.abc.Set)) # True
注意事项
- 混合元类的继承顺序必须把
ABCMeta放在EnumMeta之前,否则会触发元类初始化逻辑错误 - 三个抽象方法直接对接枚举实例自带的
value属性即可,不需要额外维护内部存储 - 该写法属于官方文档提到的第1种直接继承ABC的方案,类定义处显式标注了
collections.abc.Set继承关系,表意清晰,不需要使用虚拟子类注册的迂回方案。
内容的提问来源于stack exchange,提问作者bad_coder
相关产品推荐
相关产品推荐

