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。
我正在寻找 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。