如何在运行时更改Python对象的类型

1 投票
2 回答
723 浏览
提问于 2025-05-16 18:42

我在写代码的时候遇到了一个问题。我想在Python中使用多重继承,并且希望通过一个方法在运行时改变对象实例的类型。举个例子:

class MyClassA:
    def method(self):
        #method A

class MyClassB:
    def method(self):
        #method B

class MyClassC(MyClassA, MyClassB):
    def check():
        ...
        if isinstance(my_instance, MyClassA):
            #now you will use method of MyClassB
        else:
            # now you will use method of MyClassA

但是这个方法只在MyClass的范围内有效。我该怎么解决这个问题呢?


更新
谢谢大家的回复。我想再说得清楚一些。我有两个类,MyClassA和MyClassB,它们有相同的方法。我希望在同一个MyClassC的对象中,有时候调用MyClassA的方法,有时候调用MyClassB的方法。
所以一开始,调用instance_classC.method()时,会执行MyClassA的方法。然后在我调用了instance_classC.check()之后,我希望再调用instance_classC.method()时,这个指令能执行MyClassB的方法。

相关问题:

  • 暂无相关问题
暂无标签

2 个回答

0
class MyClassC(MyClassa, MyClassB):

    def check(self):
        self.use_b_methods = True

    def __init__(self):
        super().__init__()
        self.use_b_methods = False

    def method(self):
        if self.use_b_methods: return MyClassB.method(self)
        else return MyClassA.method(self)

这段话的意思是,你可以根据类里的一个变量来选择使用哪个方法。这并不是在运行时改变一个对象的类型。提醒一下,当你直接从定义类中选择一个方法时,你得到的是一个未绑定的方法,这时需要自己传入一个self对象,而不是系统自动给你提供。

你可以通过改变一个实例的class来改变对象的运行时类。

instance = MyType()
instance.__class__ = MyOtherType()

不过,改变class是有一些限制的,而且这样做也有一些比较大的风险。你在问题中没有描述需要改变__class的情况,所以我建议你采用我之前提到的方法。

1

这里有一个简单的继承示例:

In [351]: class A(object):
     ...:     def foo(self):
     ...:         print("<A>")
     ...:         
In [352]: class B(object):
     ...:     def foo(self):
     ...:         print('<B>')
     ...:         
In [353]: class C(A,B):
     ...:     pass
     ...: 
In [354]: c=C()
In [355]: c.foo()
<A>

默认情况下,c使用的是A.foo这个方法。

注意,instance在C和两个父类中都是True。

In [356]: isinstance(c,C)
Out[356]: True
In [357]: isinstance(c,A)
Out[357]: True
In [358]: isinstance(c,B)
Out[358]: True
In [359]: c.__class__
Out[359]: __main__.C

如果我对C进行修改,我可以选择默认的super方法,或者特别选择父类中的某个方法。

In [366]: class C(A,B):
     ...:     def foo(self):
     ...:        print('<C>')
     ...:        super().foo()
     ...:        A.foo(self)
     ...:        B.foo(self)

In [367]: c=C()
In [368]: c.foo()
<C>
<A>
<A>
<B>

关于如何使用super的更多信息,可以查看这个链接:在多重继承中更好的访问超类方法的方法

我相信在其他StackOverflow的问题中也讨论过这个。

如果我试图澄清的问题不对,你需要提供更多关于你想解决的问题的细节。

撰写回答