递归地创建子类的副本?

2024-04-16 05:09:45 发布

您现在位置:Python中文网/ 问答频道 /正文

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-方法来实现。在

^{pr2}$

但是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

在这个特定的例子中,我如何实现一个简单的、可能是递归的复制行为?在


Tags: 方法函数selfeventreturnobjectinitdef
1条回答
网友
1楼 · 发布于 2024-04-16 05:09:45

首先,MouseEvent构造函数递归地调用Event构造函数还不够吗?在

如果没有,请看一下^{} module。它基于^{}'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)

注意,如果您只需将retrieve_state()和{}分别重命名为__getstate__()和{},那么您甚至不需要copy()和{}方法,因为这样做之后,您就可以使用标准的copy()模块。(在本例中,您甚至根本不需要定义__getstate__()和{},因为默认行为是保存和恢复所有实例属性。)

相关问题 更多 >