如何在python中复制状态机类?

如何在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

下面的自包含代码段定义了一个简单的状态机,并使用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 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__()的最佳规范方法是什么?