Reputation: 31
I have a problem with my code. I want to apply the multiply inheritance in Python and I want to change the type of object instance at runtime with a method. For example:
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
But this work only in the MyClass scope. How can I solve it?
UPDATE Thank you every one for the response. I try to be more clear. I have MyClassA and MyClassB with same methods. I want to use with the same object of MyClassC, in same cases method of MyClassA and in other cases method of MyClassB. So, at begin instance_classC.method() calls the method of MyClassA. After I have called instance_classC.check(), I want that, calling instance_classC.method(), this instruction calls the method of MyClassB.
Upvotes: 1
Views: 879
Reputation: 6489
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)
That will select which method to use based on a variable in the class. That is not actually changing the type of a object at runtime. As a reminder, when you select a method directly from a defining class, you get an unbound method and need to pass in the self object rather than having it supplied for you.
You can change te runtime class of an object by changing class of an instance
instance = MyType()
instance.__class__ = MyOtherType()
However, there are restrictions on when you can change class_, and there are some significant pitfalls to doing that. You haven't described a situation in your question where you need to change __class, so I'd recommend an approach like I have described.
Upvotes: 0
Reputation: 231385
With this simple inheritance:
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>
as a default c
used the A.foo
method.
Note that instance
is True for C, and both supers.
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
If I refine C
, I can choose the default
super
method, or specifically choose the method from of the parents.
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>
More on using super
, see Better way to access super class method in multiple inheritance
I'm sure it's been discussed other SO questions.
If I'm trying to clarify the wrong question, you'll need to give more details about the problem that you are trying to solve.
Upvotes: 1