假设我有以下函数/方法,它计算一堆东西然后设置很多变量/属性:calc_and_set(obj)。
现在我想做的是用不同的对象多次调用该函数,如果一个或多个失败,则根本不应设置任何内容。
我以为我可以这样做:
try:
calc_and_set(obj1)
calc_and_set(obj2)
calc_and_set(obj3)
except:
pass
但这显然行不通。例如,如果错误发生在函数的第三次调用中,那么第一次和第二次调用将已经设置了变量。
谁能想出一种“干净”的方式来做我想做的事?我能想到的唯一解决方案是相当丑陋的解决方法。
最佳答案
我在这里看到了几个选项。
一个。具有“逆向功能”,坚固耐用。所以如果
def calc_and_set(obj):
obj.A = 'a'
def unset(obj):
if hasattr(obj, 'A'):
del obj.A
和
try:
calc_and_set(obj1)
calc_and_set(obj2)
except:
unset(obj1)
unset(obj2)
注意,在这种情况下,unset
不关心 calc_and_set
是否成功完成。
B.将calc_and_set分离为try_calc_and_set
,测试是否有效,set
不会报错,只有当所有try_calc_and_set
都没有报错时才会调用失败。
try:
try_calc_and_set(obj1)
try_calc_and_set(obj2)
calc_and_set(obj1)
calc_and_set(obj2)
except:
pass
C. (我最喜欢的)- 让 calc_and_set
返回一个新变量,而不是就地操作。如果成功,将原始引用替换为新引用。这可以通过在 calc_and_set
中添加 copy 作为第一条语句,然后返回变量来轻松完成。
try:
obj1_t = calc_and_set(obj1)
obj2_t = calc_and_set(obj2)
obj1 = obj1_t
obj2 = obj2_t
except:
pass
那个镜像当然是保存你之前的对象了:
obj1_c = deepcopy(obj1)
obj2_c = deepcopy(obj2)
try:
calc_and_set(obj1)
calc_and_set(obj2)
except:
obj1 = obj1_c
obj2 = obj2_c
作为一般性评论(如果这只是示例代码,请原谅我)- 在没有指定异常类型的情况下不要有异常。
关于python - 包含多个语句的 Try 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25984247/