捕获Python工厂类为@property赋值时抛出的所有异常
捕获@property setter的所有异常并创建MyClass实例
你想要在创建MyClass实例时,把所有@property setter抛出的异常都记录下来,而不是遇到第一个就终止流程?这好办,咱们调整一下工厂类的逻辑,用一个列表来收集所有错误,最后统一抛出就行。
首先,先补全必要的基础代码(原来的示例里有些部分不完整):
class MyException(Exception): """自定义异常,用于标记属性设置时的校验错误""" pass def sanitize(data, key): """模拟数据清洗函数,实际场景里可以做初步的数据格式转换""" return data.get(key) class MyClass(object): def __init__(self): self._age = None self._name = None @property def age(self): return self._age @age.setter def age(self, value): # 模拟年龄校验:必须是大于0的整数 if not isinstance(value, int) or value <= 0: raise MyException(f"无效年龄: {value}(需为正整数)") self._age = value @property def name(self): return self._name @name.setter def name(self, value): # 模拟姓名校验:不能为空字符串 if not isinstance(value, str) or len(value.strip()) == 0: raise MyException(f"无效姓名: '{value}'(不能为空)") self._name = value.strip()
接下来是核心的工厂类修改,重点是收集所有异常而非立即抛出:
class MyClassFactory(object): def __init__(self, data): # 先做数据清洗 cleaned_data = { "age": sanitize(data, 'age'), "name": sanitize(data, 'name') } mc = MyClass() error_list = [] # 用来存所有属性设置时的错误 # 遍历所有属性,逐个赋值并捕获异常 for prop_name, prop_value in cleaned_data.items(): try: # 调用setattr触发@property的setter校验 setattr(mc, prop_name, prop_value) except MyException as e: # 把错误信息存起来,不立即中断 error_list.append(f"属性「{prop_name}」设置失败: {str(e)}") # 如果有错误,统一抛出所有问题 if error_list: error_msg = "创建MyClass实例时发现以下错误:\n" + "\n".join(error_list) raise Exception(error_msg) self.instance = mc # 保存创建好的有效实例
关键逻辑说明
- 用
error_list列表替代原来的直接raise,这样能遍历完所有属性,把所有校验错误都收集起来。 - 最后统一抛出包含所有错误的异常,调用方可以一次性看到所有问题,不用改完一个错误再试一次。
- 如果你想更规范,可以自定义一个
MultipleValidationErrors异常类,把error_list作为属性存进去,方便后续处理。
测试示例
# 测试:传入无效的年龄(字符串)和空姓名 test_data = {"age": "25", "name": " "} try: factory = MyClassFactory(test_data) print(f"实例创建成功!姓名: {factory.instance.name}, 年龄: {factory.instance.age}") except Exception as e: print(e)
运行后会输出所有错误:
创建MyClass实例时发现以下错误: 属性「age」设置失败: 无效年龄: 25(需为正整数) 属性「name」设置失败: 无效姓名: ' '(不能为空)
内容的提问来源于stack exchange,提问作者dh762
相关产品推荐
相关产品推荐

