Python中结合枚举优化from_dict实现与get_variable方法
简洁实现方案
先看你原来可能的繁琐写法(示例)
from enum import Enum class Constants(Enum): NAME = "name_key" AGE = "age_key" EMAIL = "email_key" class MyClass: def __init__(self, name, age, email): self.name = name self.age = age self.email = email @classmethod def from_my_dict(cls, data): # 每次加新变量都要手动加一行,太麻烦 return cls( name=data[Constants.NAME.value], age=data[Constants.AGE.value], email=data[Constants.EMAIL.value] ) def get_variable(self, constant): # 新枚举加进来就得加个elif,维护成本高 if constant == Constants.NAME: return self.name elif constant == Constants.AGE: return self.age elif constant == Constants.EMAIL: return self.email raise ValueError("Invalid constant")
优化方案1:手动维护枚举-属性映射(最稳妥)
核心是在类里加一个映射表,把枚举和对应的实例属性名绑定,后续新增变量只需要更新这个表就行。
from enum import Enum class Constants(Enum): NAME = "name_key" AGE = "age_key" EMAIL = "email_key" # 后续新增枚举直接加这里 class MyClass: # 枚举 -> 实例属性名的映射,核心配置 _ENUM_ATTR_MAP = { Constants.NAME: "name", Constants.AGE: "age", Constants.EMAIL: "email", # 加新变量时同步加这一行 } def __init__(self, name, age, email): self.name = name self.age = age self.email = email @classmethod def from_my_dict(cls, data): # 批量提取字典值,不用逐个手写 kwargs = { attr_name: data[enum.value] for enum, attr_name in cls._ENUM_ATTR_MAP.items() } return cls(**kwargs) def get_variable(self, constant): try: attr_name = self._ENUM_ATTR_MAP[constant] return getattr(self, attr_name) except KeyError: raise ValueError(f"不支持的常量: {constant}")
优化方案2:自动推导属性名(省配置)
如果你的枚举名称(比如NAME)和实例属性名(比如name)是大小写对应的关系,可以不用手动写映射,直接自动推导:
from enum import Enum class Constants(Enum): NAME = "name_key" AGE = "age_key" EMAIL = "email_key" class MyClass: def __init__(self, name, age, email): self.name = name self.age = age self.email = email @classmethod def from_my_dict(cls, data): # 枚举名转小写作为属性名,批量生成参数 kwargs = { enum.name.lower(): data[enum.value] for enum in Constants } return cls(**kwargs) def get_variable(self, constant): try: attr_name = constant.name.lower() return getattr(self, attr_name) except AttributeError: raise ValueError(f"不支持的常量: {constant}")
额外提示
- 如果枚举和属性名没有规律,优先用方案1,可读性和可控性更强;
- 处理字典时可以用
data.get(enum.value)代替直接取值,避免因字典缺键抛出异常,具体看业务需求。
内容的提问来源于stack exchange,提问作者John M
相关产品推荐
相关产品推荐

