Python 将对象变为其子类的实例

Python 将对象变为其子类的实例,python,oop,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.mu

是否可以将对象变为初始对象类的派生类的实例? 比如:

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...
如果这是不可能的,我应该怎么做呢?
我的问题如下: 我的基类就像一个“摘要”,派生类就是“全部”。当然,获取“全部内容”的成本有点高,因此尽可能长时间地编写摘要是开设这两门课程的目的。但是如果你想的话,你应该能够得到它,那么再也没有必要拥有摘要了,所以对摘要的每一个引用现在都应该是(或者至少包含)全部内容。我想我必须创建一个可以同时容纳这两个对象的类,对吗

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

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

一种通用的OOP方法是使summary对象成为一个Façade,将昂贵的操作委托给一个(动态构造的)后端对象。你甚至可以使它完全透明,这样对象的调用者就看不到发生了什么事情(当然,除非他们开始计时)。

我忘了说我还想从一开始就创建一个“整件事”,而不是一个不需要的摘要。 我终于这样做了:

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

就像一个符咒:)

你不能指定给
self
去做你想做的事情,但是你可以通过在你的mutate方法中指定给
self.\uu class\uuuu
来改变对象的类


然而,这确实是一种糟糕的做法——在您的情况下,委派比继承要好

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

def mutate(self):
    self.__class__ = Derived
将完全执行请求的操作--将self的类更改为
派生的
,而不是
基的
。这不会自动执行
Derived.\uuuuu init\uuuuu
,但如果需要,可以显式调用它(例如,作为
self.\uuuu init\uuuu()
,作为方法中的第二条语句)

对于OP的实际问题来说,这是否是一个好方法,与最初的问题完全不同

有可能改变一个对象吗 到的派生类的实例中 首字母的对象类


对此的答案是“是的,这是可能的”(这就是我刚才展示的方式)。“这是解决我的具体应用问题的最佳方法”与“是否可能”是不同的问题

还要注意,Façade和Delegate都是软件模式的类型,这就是我将它们大写的原因。如果你以前从未遇到过他们,现在是学习的好时机。谢谢你的回答。我最终用另一种方法实现了它,因为这是一个简单的类,这样我就不需要委托模式所需要的多个类。但我可以看出,对于更复杂的情况,这将是一个很好的解决方案。谢谢@戈胡:正面是对细节集合的“总结”。有两个班。一点也不复杂。这是一种更简单的方法,因为您可以正确地将“摘要”与“细节”分开。不要这样做。摘要和细节是不同的事情。它们不是超类和子类,就像“Float”是“Number”的子类一样。您有一个摘要,它是详细信息的容器,并且具有相同的界面。他们是同龄人,不是父母和孩子。