如何将字典键映射至对应类?求替代if判断的优化方案
字典键到相似名称类的最优映射方法
你需要把字典中名称相似但不完全一致的键,映射到对应的自定义异常类,替代冗余的if判断,这里提供几种高效实用的方案:
方案一:显式映射字典(最安全、易维护)
直接创建键与类的映射字典,逻辑清晰直观,后续新增类只需更新字典即可,彻底避免条件判断。
errors = { 'BadRequest': { 'title': "Some title", 'description': "Some description" }, 'NotFoundError': { 'title': "Some title2", 'description': "Some description2" } } class HttpException(Exception): title: str description: str class HttpNotFound(HttpException): def __init__(self, title: str, description: str): self.title = title self.description = description class HTTPBadRequest(HttpException): def __init__(self, title: str, description: str): self.title = title self.description = description # 显式定义键与类的对应关系 KEY_TO_CLASS = { 'BadRequest': HTTPBadRequest, 'NotFoundError': HttpNotFound } def data_to_object(errors): data = [] for key, value in errors.items(): cls = KEY_TO_CLASS.get(key) if cls: # 修正原代码的参数错误,传入正确的description值 data.append(cls(title=value['title'], description=value['description'])) return data list_of_objects = data_to_object(errors)
方案二:字符串转换自动匹配(适合命名规则固定的场景)
如果键和类名的转换规则固定(比如BadRequest对应HTTPBadRequest,NotFoundError对应HttpNotFound),可以通过字符串处理自动匹配类,减少手动维护映射的工作量,但要确保命名规则严格统一。
errors = { 'BadRequest': { 'title': "Some title", 'description': "Some description" }, 'NotFoundError': { 'title': "Some title2", 'description': "Some description2" } } class HttpException(Exception): title: str description: str class HttpNotFound(HttpException): def __init__(self, title: str, description: str): self.title = title self.description = description class HTTPBadRequest(HttpException): def __init__(self, title: str, description: str): self.title = title self.description = description def get_exception_class(key: str): # 根据键名生成对应的类名,可根据实际命名规则扩展逻辑 if key == 'BadRequest': return 'HTTPBadRequest' elif key == 'NotFoundError': return 'HttpNotFound' return None def data_to_object(errors): data = [] for key, value in errors.items(): class_name = get_exception_class(key) if class_name: # 从全局作用域获取对应类 cls = globals().get(class_name) if cls and issubclass(cls, HttpException): data.append(cls(title=value['title'], description=value['description'])) return data list_of_objects = data_to_object(errors)
方案三:装饰器注册类(适合大量类的场景)
如果需要映射的异常类数量较多,用装饰器自动注册类到映射字典,后续新增类只需添加装饰器,无需手动修改映射。
# 全局映射字典 KEY_TO_CLASS = {} def register_exception(key: str): def decorator(cls): KEY_TO_CLASS[key] = cls return cls return decorator class HttpException(Exception): title: str description: str @register_exception('NotFoundError') class HttpNotFound(HttpException): def __init__(self, title: str, description: str): self.title = title self.description = description @register_exception('BadRequest') class HTTPBadRequest(HttpException): def __init__(self, title: str, description: str): self.title = title self.description = description errors = { 'BadRequest': { 'title': "Some title", 'description': "Some description" }, 'NotFoundError': { 'title': "Some title2", 'description': "Some description2" } } def data_to_object(errors): data = [] for key, value in errors.items(): cls = KEY_TO_CLASS.get(key) if cls: data.append(cls(title=value['title'], description=value['description'])) return data list_of_objects = data_to_object(errors)
各方案优劣对比
- 显式映射字典:最推荐,安全直观,排查问题简单,适合类数量不多的场景。
- 字符串转换:适合命名规则固定的场景,减少手动维护,但规则变动时需同步修改转换逻辑,且使用
globals()存在一定安全风险(键名可控时可忽略)。 - 装饰器注册:适合大量类的场景,新增类更便捷,代码更整洁。
内容的提问来源于stack exchange,提问作者Chaban33
相关产品推荐
相关产品推荐

