Python对象属性回滚
有时候当我们执行一个过程复杂的任务,如果任务失败了我们不想它改变之前的数据,就是回到任务执行前的状态,类似如数据库中常用的回滚。
实现代码:
from copy import copy, deepcopy
def memento(obj, deep=False):
state = deepcopy(obj.__dict__) if deep else copy(obj.__dict__)
def restore():
obj.__dict__.clear()
obj.__dict__.update(state)
return restore
class Transactional:
def __init__(self, method):
self.method = method
def __get__(self, obj, T):
def transaction(*args, **kwargs):
state = memento(obj)
try:
return self.method(obj, *args, **kwargs)
except Exception as e:
state()
print(str(e))
return transaction
我们先定义一个函数,用于存储对象改变前的所有属性,可选择深拷贝或浅拷贝,根据具体需求而定。
然后定义一个用于回滚的装饰器,在装饰器中我们捕获任务在执行时可能出现的异常,如果出现错误则把刚刚保存的属性都重新取回来,这里根据实际场景可以捕获不同的异常,也可以更改要不要抛出异常。
测试一下:
class Count:
def __init__(self):
self.val = 0
def add(self, n):
self.val += n
@Transactional
def run(self, num_list):
for n in num_list:
self.add(n)
print(self.val)
if __name__ == '__main__':
c = Count()
print(c.val)
s = [1, 2, 'x', 3]
c.run(s)
print(c.val)
输出:
0
1
3
unsupported operand type(s) for +=: 'int' and 'str'
0
可以看到val的值在中途是有变化的,但遇到错误后又变成之前的0。