如何在python中复制状态机类?
下面的自包含代码段定义了一个简单的状态机,并使用copy模块对其进行复制如何在python中复制状态机类?,python,copy,state-machine,Python,Copy,State Machine,下面的自包含代码段定义了一个简单的状态机,并使用copy模块对其进行复制 import copy class StateMachine: def __init__(self): self.doit = self._doit_A def _doit_A(self): print('state A') self.doit = self._doit_B def _doit_B(self): print('state
import copy
class StateMachine:
def __init__(self):
self.doit = self._doit_A
def _doit_A(self):
print('state A')
self.doit = self._doit_B
def _doit_B(self):
print('state B')
self.doit = self._doit_A
sm = StateMachine()
sm_copy_before_changes = copy.copy(sm)
print('--- Original StateMachine ---')
for _ in range(3): sm.doit()
print('--- pre copy ---')
for _ in range(3): sm_copy_before_changes.doit()
sm_copy_after_changes = copy.copy(sm)
print('--- post copy ---')
for _ in range(3): sm_copy_after_changes.doit()
输出是
--- Original StateMachine ---
state A
state B
state A
--- pre copy ---
state A
state A
state A
--- post copy ---
state B
state B
state B
在后续的doit()
调用中,原始状态机按预期从一个状态切换到下一个状态
在对原始文件进行任何doit()
调用之前所做的复制被卡在状态A中
在原始文件中进行doit()
调用后生成的副本将卡在状态B中
为什么这不起作用?让副本按预期工作的最佳方法是什么?
deepcopy()。什么是copy()
忽略deepcopy()
在这种情况下不会忽略的内容
在我面前的现实世界中,我不想deepcopy()
状态机。大概我可以重新定义\uuuuu copy\uuuu()
?在这种情况下我该怎么做?或者我应该重新定义\uuu deepcopy\uuu()
?好的,您只需要检查对象:
assert sm.doit==sm\u copy\u before\u changes.doit
sm\u更改前复制,sm,sm\u更改前复制。doit
给出:
,
,
因此,当您复制
时,您创建了一个新对象-但是,它的doit
仍然引用sm
的doit
对象-因此,显然它处于一种状态
现在,让我们试试deepcopy
sm\u before\u 2=copy.deepcopy(sm)
在2.doit之前断言sm_!=sm.doit
在你2之前,在你2之前
给出:
,
好吧,那现在显然有效了
这一点在本书中有所提及
浅复制构造一个新的复合对象,然后(尽可能)向其中插入对原始对象的引用
深度副本构造一个新的复合对象,然后递归地将在原始副本中找到的对象的副本插入其中
黑客攻击\uuuu复制\uuuuuu
:
黑客\uuuu copy\uuuu
的一种非常快速的方法是:
def\uuuu复制(自):
新=自我。_uu类_;()
对于i-in-dir(self):
如果我__weakref___':
setattr(新的,i,getattr(self,i))
还新
显然,要小心测试,这样你的应用程序中就不会出现任何意外后果 我不确定我是否理解正确,请看我的答案并告诉我这是否是你想要的。谢谢Partha。因此,看起来Python方法链接到它们操作的对象实例,调用对象可能是或可能不是相同的,而不是C++方法,其中方法链接到类,调用实例确定它们操作的对象。很公平。那么,在这个实例中,我如何重写< C++ >代码> <代码>以获得C++样式的行为?我不想依赖deepcopy()
,因为它不适合现实生活中的用例。@OldSchool我很想知道你为什么对deepcopy
有点担心-我的意思是显而易见的;正如你所说的,你有一个真实世界的问题-但是,到底是什么(如果可以简要介绍的话)?@OldSchool还添加了一个快速的hack来重载\uuuuuuu copy\uuuuuu
真实世界的状态机包含对不需要复制的大型结构的引用。这就是为什么我不想在你说“黑客”的时候说“黑客”:作为一名黑客,在你的实现中有什么关系?为了获得我所描述的行为,这个类重写_copy__()的最佳规范方法是什么?