Python: 保存和恢复数据成员的装饰器

Python: a decorator to save and restore data member

我正在寻找 python 装饰器来实现 'save & restore' 功能。我想要的是一个装饰器,它保存一个对象实例的一些数据成员,执行一个可以改变这些数据成员的方法,并恢复实例的旧状态。这是一个最小的例子:

class toto:
    def __init__(self):
        self.myMember = []

    def update(self,var):
        self.myMember.append(var)

    def preserveMember(func):
        def dec(self):
            oldMember = self.myMember
            func(self)
            self.myMember = oldMember
            return
        return dec

    @preserveMember
    def doJob(self):
        self.update('haha!!')
        print "doJob: "+self.myMember.__repr__()


if __name__ == '__main__':
    tt = toto()

    tt.update('tutu1')
    tt.update('tutu2')

    print "Before Job: "+ tt.myMember.__repr__()
    tt.doJob()
    print "After Job: "+ tt.myMember.__repr__()

这段代码的输出是

Before Job: ['tutu1', 'tutu2']
doJob: ['tutu1', 'tutu2', 'haha!!']
After Job: ['tutu1', 'tutu2', 'haha!!']

但是我想要的装饰器preserveMember

Before Job: ['tutu1', 'tutu2']
doJob: ['tutu1', 'tutu2', 'haha!!']
After Job: ['tutu1', 'tutu2']

我觉得我迷失了可变范围,但我不知道在哪里寻找这样的功能。任何想法都会有所帮助,谢谢! (更多信息:我正在使用 Python 2.7)

您的装饰器适用于将通过覆盖更改的成员。但是,有问题的成员是一个列表,它是通过引用保存和恢复的。这意味着当作业改变列表时,它也会改变保存的值,因为它是完全相同(相同)的列表实例。

如果您确定该成员始终是一个列表,您需要做的是保存并恢复旧对象,但在其位置放置一个副本以便作业发生变化:

def preserveMember(func):
    def dec(self):
        oldMember = self.myMember
        self.myMember = self.myMember[:]
        func(self)
        self.myMember = oldMember
    return dec

更新:在一般情况下,copy模块可用于创建成员的"deep copy":

import copy

def preserveMember(func):
    def dec(self):
        oldMember = self.myMember
        self.myMember = copy.deepcopy(self.myMember)
        func(self)
        self.myMember = oldMember
    return dec

如果涉及自定义对象,它们可以实现如何deepcopy它们的实例。参见 the documentation of the copy module