如何在运行时使用python更改一种对象

时间:2017-04-28 15:23:13

标签: python inheritance

我的代码有问题。我想在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 :(得分: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方法。

请注意,对于C,instance为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,我可以选择default 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的更多信息,请参阅Better way to access super class method in multiple inheritance

我确信已经讨论了其他SO问题。

如果我想澄清错误的问题,您需要提供有关您要解决的问题的更多详细信息。

答案 1 :(得分: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对象而不是为您提供它。

您可以通过更改实例的来更改对象的运行时类

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

但是,对于何时可以更改 class_存在限制,并且存在一些重要的陷阱。您没有在问题中描述需要更改__class 的情况,因此我建议采用我所描述的方法。