循环创建对象失败时如何记录日志且不终止循环?实现咨询
问题解答
一、原实现的合理性分析
原实现的逻辑是合理的,但存在可优化的细节:
- 自定义
DivisionCreationError的核心价值,是把底层的ZeroDivisionError封装成业务层面的异常,让调用方无需关心具体的底层错误类型,只需聚焦「Division对象创建失败」这个业务结果。这种封装在复杂业务场景下扩展性很强——比如后续新增其他创建失败场景(如传入非数字参数),可以统一抛出该自定义异常,调用方的处理逻辑无需修改。 - 但原代码里在
try块中先执行self.a / self.b做检查,又在else块中重复计算赋值给self.result,属于冗余操作,可直接优化为:
这样既完成了有效性校验,又避免了重复计算。try: self.result = self.a / self.b except ZeroDivisionError: logging.warning('Not possible') raise DivisionCreationError
如果你的业务场景极简单(仅存在除零这一种失败可能),直接在调用方捕获ZeroDivisionError也能运行,但自定义异常的扩展性优势依然存在。
二、改为「创建失败返回None,用if判断」的实现方式
完全可以,这种方式更偏向「返回值判断」的风格,适合错误场景相对常见的情况。核心思路是用工厂方法替代直接调用构造函数,确保对象要么完全有效,要么返回None,避免出现半初始化的无效对象:
修改后的代码示例
import logging class Division(object): # 构造函数仅负责初始化合法参数,保证对象创建后状态有效 def __init__(self, a, b, result): self.a = a self.b = b self.result = result def get_result(self): return self.result # 工厂类方法:统一处理对象创建逻辑,失败返回None @classmethod def create(cls, a, b): try: result = a / b return cls(a, b, result) except ZeroDivisionError: logging.warning('Not possible') return None if __name__ == '__main__': numbers = [(1,2), (1,0), (1,3)] for num_pair in numbers: created_object = Division.create(num_pair[0], num_pair[1]) # 通过if判断对象是否创建成功 if created_object: print(created_object.get_result())
实现思路说明
- 拆分原构造函数
__init__的职责:__init__仅负责初始化有效对象,不再处理异常逻辑; - 新增类方法
create作为工厂方法,统一管控对象创建流程——成功则返回完整的Division对象,失败则返回None并记录日志; - 调用方通过
if created_object:判断对象是否存在,存在则执行后续方法调用。
这种方式的优势是:不会出现「对象已创建但处于无效状态」的情况,代码可读性更强,适合对异常处理风格偏好较低的场景。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

