Python 递归地创建子类的副本?
类Python 递归地创建子类的副本?,python,class,copy,Python,Class,Copy,类Event实现一个函数copyFrom(self,Event)和copy(self)。这两种方法的实现都很简单 class Event(object): def __init__(self, a, b): self.a = a self.b = b def copyFrom(self, event): self.a = event.a self.b = event.b def copy(self):
Event
实现一个函数copyFrom(self,Event)
和copy(self)
。这两种方法的实现都很简单
class Event(object):
def __init__(self, a, b):
self.a = a
self.b = b
def copyFrom(self, event):
self.a = event.a
self.b = event.b
def copy(self):
return Event(self.a, self.b)
现在,子类MouseEvent
希望覆盖这两个类。第一个方法,copyFrom(self,event)
可以通过调用super方法来实现
但是复制(自我)
呢?当然,仅仅创建一个新对象并不难
# ...
def copy(self):
return MouseEvent(self.a, self.b, self.c, self.d)
但是如果事件
类拥有一些私有属性怎么办?想要将其子类化的人不想关心它们
class Event(object):
def __init__(self, a, b):
self.a = a
self.b = b
self._aab = fancyFunction(a, b)
def doStuff(self, c):
self._aab <<= c * 2
def copyFrom(self, event):
self.a = event.a
self.b = event.b
self._aab = event._aab
def copy(self):
e = Event(self.a, self.b)
e._aab = self._aab
return e
在这个特定的示例中,我如何实现一个简单的、可能是递归的复制行为?首先,
MouseEvent
构造函数递归调用事件
构造函数还不够吗
如果没有,请查看。它是基于。使用此协议,递归调用很容易。如果您不想遵循pickle
接口,当然可以复制这个基本设计,因为我不认为这样做有任何好处
编辑:我似乎没能理解这个信息,事实上我的回答可能有点模糊。因此,我们在这里使用建议的设计进行代码示例:
class Event(object):
def __init__(self, a, b):
self.a = a
self.b = b
self._aab = fancyFunction(a, b)
def retrieve_state(self):
return self.a, self.b, self._aab
def restore_state(self, state):
self.a, self.b, self._aab = state
def copy_from(self, event):
self.restore_state(event.retrieve_state())
def copy(self):
e = object.__new__(self.__class__)
e.restore_state(self.retrieve_state())
return e
class MouseEvent(Event):
def __init__(self, a, b, c, d):
Event.__init__(self, a, b)
self.c = c
self.d = d
def retrieve_state(self):
event_state = super(MouseEvent, self).retrieve_state()
return event_state, self.c, self.d
def restore_state(self, state):
event_state, self.c, self.d = state
super(MouseEvent, self).restore_state(event_state)
请注意,如果您只需分别将
retrieve\u state()
和restore\u state()
重命名为\u getstate\u()
和\u setstate\u()
,您甚至不需要copy\u from()
方法,因为这样做之后,您可以使用标准的copy()
模块。(在本例中,您甚至不需要定义\uuu getstate\uuuu()
和\uu setstate\uuuu()
,因为默认行为是保存和恢复所有实例属性。)但是,正如我所说的,如果事件
-类拥有私有属性怎么办?请看一下(添加的)示例代码。对于复制
模块,我需要再次创建一个函数\uuuu复制
,不是吗?@NiklasR:1。行e.\u aab=self.\u aab
是冗余的。该函数在调用之前调用MouseEvent
构造函数,后者依次调用Event()
,后者依次正确设置e.\u aab
,因此没有问题。这就是我回答的第一句话的意思。2.如果您出于某种原因不喜欢这样做,请在类上实现\uuu getstate\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
和\uu。它们中的每一个都可以调用相应的基类函数。这里的要点是将复制分为两部分,状态检索和状态恢复。这使得确保封装变得很容易。“行e.\u aab=self.\u aab是冗余的”-它不是冗余的,用户可以在调用Event.doStuff(self,c)
时修改\u aab
。实际上,我不明白这与酸洗有什么关系,对不起。@NiklasR:你问了一个如何在保持封装的同时实现实例复制的设计,我建议了一个在保持封装的同时实现实例复制的设计——即Python的copy
模块的设计,顺便说一句,它依赖于pickle
协议。此设计的中心点是状态检索和恢复的分离,这使得使用递归调用变得容易。您可以复制此设计并定义自己的状态检索和恢复协议,也可以使用copy
模块经常使用的协议。啊哈!代码让我明白了!这真是个好设计。我会用的。非常感谢。
class MouseEvent(Event):
# ...
def copy(self):
e = MouseEvent(self.a, self.b, self.c, self.d)
e._aab = self._aab
return e
class Event(object):
def __init__(self, a, b):
self.a = a
self.b = b
self._aab = fancyFunction(a, b)
def retrieve_state(self):
return self.a, self.b, self._aab
def restore_state(self, state):
self.a, self.b, self._aab = state
def copy_from(self, event):
self.restore_state(event.retrieve_state())
def copy(self):
e = object.__new__(self.__class__)
e.restore_state(self.retrieve_state())
return e
class MouseEvent(Event):
def __init__(self, a, b, c, d):
Event.__init__(self, a, b)
self.c = c
self.d = d
def retrieve_state(self):
event_state = super(MouseEvent, self).retrieve_state()
return event_state, self.c, self.d
def restore_state(self, state):
event_state, self.c, self.d = state
super(MouseEvent, self).restore_state(event_state)