备忘录模式

import copy

def Memento(obj, deep=False):

    # 对你要做快照的对象做快照
    state = (copy.copy if deep else copy.deepcopy)(obj.__dict__)
    def Restore():
        obj.__dict__ = state
    return Restore

class Transaction:

    deep = False
    def __init__(self, *targets):
        self.targets = targets
        self.Commit()
    # 模拟事务提交,其实就是初始化给每个对象往self.targets赋值
    def Commit(self):
        self.states = [Memento(target, self.deep) for target in self.targets]
    # 回滚其实就是调用Memento函数,执行其中的闭包,将__dict__恢复
    def Rollback(self):
        for state in self.states:
            state()

# 装饰器的方式给方法添加这个事务的功能
def transactional(method):
    # 这里的self其实就是要保存的那个对象,和类的实例无关
    def wrappedMethod(self, *args, **kwargs):
        state = Memento(self)
        try:
            return method(self, *args, **kwargs)
        except:
            # 和上面的回滚一样,异常就恢复
            state()
            raise
    return wrappedMethod

class NumObj(object):
    def __init__(self, value):
        self.value = value
    def __repr__(self):
        return '<%s: %r>' % (self.__class__.__name__, self.value)
    def Increment(self):
        self.value += 1

    @transactional
    def DoStuff(self):
        # 赋值成字符串,再自增长肯定会报错的
        self.value = '1111'
        self.Increment()

if __name__ == '__main__':

    n = NumObj(-1)
    print n
    t = Transaction(n)
    try:
        for i in range(3):
            n.Increment()
            print n
        # 这里事务提交会保存状态从第一次的-1到2
        t.Commit()
        print '-- commited'
        for i in range(3):
            n.Increment()
            print n
        n.value += 'x' # will fail
        print n
    except:
        # 回滚只会回顾到上一次comit成功的2 而不是-1
        t.Rollback()
        print '-- rolled back'
    print n
    print '-- now doing stuff ...'
    try:
        n.DoStuff()
    except:
        print '-> doing stuff failed!'
        import traceback
        traceback.print_exc(0)
        pass
    # 第二次的异常回滚n还是2, 整个过程都是修改NumObj的实例对象
    print n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值