课程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 -method来实现。
class MouseEvent(Event):
def __init__(self, a, b, c, d):
super(Event, self).__init__(a, b)
self.c = c
self.d = d
def copyFrom(self, event):
super(Event, self).copyFrom(event)
self.c = event.c
self.d = event.d
但是copy(self)
呢?当然,创建一个新对象并不难。
# ...
def copy(self):
return MouseEvent(self.a, self.b, self.c, self.d)
但如果Event
类拥有某些私有属性会怎么样?想要继承它的人,不想关心它们!
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
copy(self)
的这种实现现在看起来很脏,来自MouseEvent
的重写也是如此。
class MouseEvent(Event):
# ...
def copy(self):
e = MouseEvent(self.a, self.b, self.c, self.d)
e._aab = self._aab
return e
如何在这个特定的例子中实现一个简单的,可能是递归的副本 -behaviour?
答案 0 :(得分:3)
首先,MouseEvent
构造函数递归调用Event
构造函数是不够的?
如果没有,请查看copy
module。它基于pickle
's state retrieval and restoration protocol。使用此协议,递归调用很容易。如果你不想符合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)
请注意,如果您只需将copy()
和copy_from()
重命名为retrieve_state()
和{{1},则甚至不需要restore_state()
和__getstate__()
方法分别是因为在编码之后你可以使用标准的__setstate__()
模块。 (在手头的情况下,您根本不需要定义copy()
和__getstate__()
,因为默认行为是保存和恢复所有实例属性。)