将对象变为其子类的一个实例

时间:2010-05-22 09:54:24

标签: python oop

是否可以将对象变为初始对象类的派生类的实例? 类似的东西:

class Base():
    def __init__(self):
        self.a = 1

    def mutate(self):
        self = Derived()

class Derived(Base):
    def __init__(self):
        self.b = 2

但这不起作用。

>>> obj = Base()
>>> obj.mutate()
>>> obj.a
1
>>> obj.b
AttributeError...

如果无法做到这一点,我该怎么办? 我的问题如下: 我的Base类就像一个“摘要”,Derived类就是“整体”。当然,获取“整件事”有点贵,所以只要有可能是这两个类的重点就在编写摘要。但是如果你愿意的话,你应该能够得到它,然后就不再有摘要了,所以每次对摘要的引用现在都应该(或者至少包含)整个事情。我想我必须创建一个可以容纳两者的类,对吧?

class Thing():
    def __init__(self):
        self.summary = Summary()
        self.whole = None

    def get_whole_thing(self):
        self.whole = Whole()

4 个答案:

答案 0 :(得分:6)

一般的OOP方法是使摘要对象成为一个Façade,它将昂贵的操作委托给(动态构造的)后端对象。你甚至可以让它完全透明,这样对象的调用者就不会发现有任何事情发生了(好吧,除非他们当然开始计时)。

答案 1 :(得分:6)

回复提出的原始问题,将mutate方法更改为:

def mutate(self):
    self.__class__ = Derived

将完全按照要求执行操作 - 将自己的课程更改为Derived而不是Base。这不会自动执行Derived.__init__,但如果需要,可以显式调用它(例如,self.__init__()作为方法中的第二个语句。)

对于OP的实际问题,这是否是良好的方法是一个完全不同的问题,而不是原始问题,

  

是否可以改变对象   到一个派生类的实例   初始的对象类?

对此的答案是“是的,它是可能的”(并且它按照我刚刚展示的方式完成)。 “对于我的特定应用程序问题,它是最好的方法”是不同的问题,而不是“它是否可能”; - )

答案 2 :(得分:1)

我忘了说我也希望能够从一开始就创建一个“整体”,如果不需要则不是摘要。 我终于这样做了:

class Thing():
    def __init__(self, summary=False):
        if summary:
            self.summary = "summary"
            self._whole = None
        else:
            self._whole = "wholething"

    @property
    def whole(self):
        if self._whole: return self._whole
        else:
            self.__init__()
            return self._whole

像魅力一样工作:)

答案 3 :(得分:0)

您不能指定self来执行您想要的操作,但您可以通过在mutate方法中指定self.__class__来更改对象的类。

然而,这是非常糟糕的做法 - 对于你的情况,委托比继承更好。