Reputation: 3159
As far as I understand, in Python methods of parent class are overridden. So all class methods are virtual by default as can be seen from the code below.
class Parent(object):
def Method1(self):
print 'FOO'
class Child(Parent):
def Method1(self):
print 'BAR'
myInstance = Child()
#Overridden method is called
myInstance.Method1() # BAR
#Is it possible to do the following?
myInstance.{something} # FOO
QUESTIONS:
Is it possible to call parent method Parent.Method1()
from the instance myInstance
of the child class?
Is it possible to make def Parent.Method1(self)
not to be overridden by a method with the same name, but some different set of arguments def Child.Method1(self,x,y)
?
Upvotes: 1
Views: 891
Reputation: 1124110
You call parent methods by having the super()
function search for the next method in the MRO (method resolution order):
class Child(BaseClass):
def Method1(self):
print 'BAR'
super(Child, self).Method1() # will call BaseClass.Method1
where self
is the instance reference, so super(type(myInstance), myInstance).Method1()
would achieve the same thing from outside the method.
Or you can access the unbound method on the class, and pass in the instance explicitly; you'd be able to do this outside the method too:
BaseClass.Method1(myInstance)
because now you referenced the method attribute directly on the class instead, and passed in the instance as an explicit self
to that method; you'd use self
from inside a method on Child
there.
Python attributes (methods are attributes too) are looked up by name and such look-ups search through the instance, then the class of the instance, then through each parent class until a match is found; the signature of a method doesn't come into play here.
You can still override a method in a child class, change the signature, but remain compatible with the parent method by using keyword arguments:
class Child(BaseClass):
def Method1(self, x=None, y=None):
if x is None and y is None:
# arguments left at defaults, call base method
return super(Child, self).Method1()
print 'BAR: {} and {}'.format(x, y)
Now if you call myInstance.Method1()
, with no arguments, the BaseClass.Method1()
method is called, pass in arguments and something else happens instead.
Upvotes: 2
Reputation: 532053
In addition to using super
, there are a couple of explicit options that bypass the MRO:
# Explicitly call Baseclass.Method1, passing your instance as the argument
BaseClass.Method1(myInstance)
# Call Method1 on the (first) base class of the instance.
# This is ugly; don't actually write code like this
# x.__class__.__bases__[0] is just another way to get a reference
# to BaseClass; otherwise, this is identical to the previous option,
# hence the need to repeat myInstance
myInstance.__class__.__bases__[0].Method1(myInstance)
Upvotes: 1
Reputation: 36852
Is it possible to call parent method Parent.Method1() from the instance myInstance of the child class?
You can call the method directly, and pass your instance as first argument:
>>> class A(object):
... def foo(self):
... print 'foo'
...
>>> class B(A):
... def foo(self):
... print 'bar'
...
>>> b = B()
>>> A.foo(b)
foo
Is it possible to make def Parent.Method1(self) not to be overridden by a method with the same name, but some different set of arguments def Child.Method1(self,x,y)?
Yes, you use super and call the parent's method directly:
>>> class A(object):
... def foo(self, bar='bar'):
... print bar
...
>>> class B(A):
... def foo(self):
... super(B, self).foo(bar='foo')
...
>>> B().foo()
foo
>>> A().foo()
bar
Upvotes: 1