如何在createObj函数层级处理Obj_A方法抛出的异常?
解决方案:在createObj层级处理返回对象方法的异常
直接结论:可以实现,但常规的try/except无法直接覆盖返回对象后续方法调用的异常——因为createObj执行完毕返回实例后,方法调用是独立的后续流程。需要通过包装实例方法或代理类的方式,把异常处理逻辑绑定到返回的实例上。
场景重现(原始问题代码)
class Obj_B: def __init__(self): raise ValueError("Don't divide by zero") class Obj_A: def myFunc(self, var): Obj_B() def createObj(): try: return Obj_A() except Exception: print("Bad boy!") # 调用时异常会直接抛出,createObj里的try捕获不到 # createObj().myFunc('var')
方法1:包装指定方法(针对myFunc)
在createObj创建Obj_A实例后,重写它的myFunc方法,给方法添加异常捕获逻辑:
class Obj_B: def __init__(self): raise ValueError("Don't divide by zero") class Obj_A: def myFunc(self, var): Obj_B() def createObj(): try: obj_a = Obj_A() # 保存原始方法 original_myfunc = obj_a.myFunc # 定义带异常捕获的包装方法 def wrapped_myfunc(var): try: return original_myfunc(var) except Exception: print("Bad boy!") # 替换原方法 obj_a.myFunc = wrapped_myfunc return obj_a except Exception: print("Bad boy!") # 调用时无需捕获异常,异常会被包装后的方法处理 createObj().myFunc('var')
方法2:代理类(统一处理所有方法)
如果Obj_A有多个方法需要处理异常,用代理类更高效。代理类拦截所有方法调用,统一添加异常捕获:
class Obj_B: def __init__(self): raise ValueError("Don't divide by zero") class Obj_A: def myFunc(self, var): Obj_B() # 定义代理类 class Obj_AProxy: def __init__(self, target_obj): self.target = target_obj # 拦截属性/方法访问 def __getattr__(self, attr_name): target_attr = getattr(self.target, attr_name) # 如果是可调用方法,包装后返回 if callable(target_attr): def wrapped_method(*args, **kwargs): try: return target_attr(*args, **kwargs) except Exception: print("Bad boy!") return wrapped_method # 非方法属性直接返回 return target_attr def createObj(): try: obj_a = Obj_A() # 返回代理对象而非原始实例 return Obj_AProxy(obj_a) except Exception: print("Bad boy!") # 调用任意方法都会触发异常处理 createObj().myFunc('var')
说明
- 方法1适合只需要处理单个或少数方法的场景,逻辑简单直接。
- 方法2适合需要统一处理多个方法异常的场景,扩展性更强,新增方法无需修改包装逻辑。
内容的提问来源于stack exchange,提问作者braunlee
相关产品推荐
相关产品推荐

