Python如何实现可交叉引用的固定不可变命名条目集合?
解决方案
问题核心原因
Enum类定义阶段,所有成员的原始赋值还未被封装为枚举实例,同时Item类本身未完成初始化,无法直接引用已实例化的枚举成员,因此直接写ITEM_A或者Item.ITEM_A都会报错。
方案1:基于现有Enum最小改造(推荐,保留Enum所有特性)
核心思路:定义阶段用枚举成员的字符串名称标记依赖,在__init__阶段(此时所有枚举实例已经完成注册到类的__members__映射中)统一将字符串替换为真实的枚举实例,同时直接支持你需要的字典类型requirements。
import enum class Item(enum.Enum): ITEM_A = {"size": 100, "requirements": {}} ITEM_B = {"size": 200, "requirements": {"ITEM_A": 1}} # 支持任意顺序的交叉引用,例如: # ITEM_C = {"size": 300, "requirements": {"ITEM_A": 2, "ITEM_B": 1}} def __new__(cls, *args, **kwds): value = len(cls.__members__) + 1 obj = object.__new__(cls) obj._value_ = value return obj def __init__(self, values: dict): self.size = values["size"] # 批量替换依赖的字符串名称为真实枚举实例 self.requirements = {} for item_name, count in values["requirements"].items(): self.requirements[self.__class__[item_name]] = count
功能验证
# 枚举成员仍可正常作为字典键使用 available = {Item.ITEM_A: 22, Item.ITEM_B: 45} print(available[Item.ITEM_A]) # 输出22 # 依赖扣减逻辑可正常执行 for r_item, r_count in Item.ITEM_B.requirements.items(): available[r_item] -= r_count print(available[Item.ITEM_A]) # 输出21,符合预期
方案2:普通类实现(不需要Enum特性的场景)
如果不需要Enum的遍历、按名/值查找等内置能力,可以用不可变普通类实现,手动预定义实例即可解决引用问题:
class Item: # 关闭动态属性修改,实现不可变 __slots__ = ("_value", "size", "requirements") def __init__(self, value: int, size: int, requirements: dict): self._value = value self.size = size self.requirements = requirements # 实现哈希和相等判断,支持作为字典键 def __hash__(self): return hash(self._value) def __eq__(self, other): return isinstance(other, Item) and self._value == other._value # 按顺序初始化实例,后面的实例可直接引用前面已初始化的实例 ITEM_A = Item(1, 100, {}) ITEM_B = Item(2, 200, {ITEM_A: 1})
内容的提问来源于stack exchange,提问作者Arne Mertz
相关产品推荐
相关产品推荐

