Python using derived class's method in parent class?
Asked Answered
M

2

11

Can I force a parent class to call a derived class's version of a function?

class Base(object):
    attr1 = ''
    attr2 = ''

    def virtual(self):
        pass               # doesn't do anything in the parent class

    def func(self):
        print "%s, %s" % (self.attr1, self.attr2)
        self.virtual()

and a class that derives from it

class Derived(Base):
    attr1 = 'I am in class Derived'
    attr2 = 'blah blah'

    def virtual(self):
        # do stuff...
        # do stuff...

Clearing up vagueness:

d = Derived()
d.func()         # calls self.virtual() which is Base::virtual(), 
                 #  and I need it to be Derived::virtual()
Molecular answered 19/2, 2010 at 16:25 Comment(3)
sorry about that, changed the question to be less vagueMolecular
Using python 2.6.4 and putting print in the derived virtual - it uses the derived virtual function - not BaseChaddie
what makes you think it is calling Base::virtual()?Riane
C
9

If you instantiate a Derived (say d = Derived()), the .virtual that's called by d.func() is Derived.virtual. If there is no instance of Derived involved, then there's no suitable self for Derived.virtual and so of course it's impossible to call it.

Caterwaul answered 19/2, 2010 at 16:29 Comment(3)
your right of course... been too quick again. It happens to me too often these days ;-(Yi
I changed the question to better explain what i meanMolecular
Paul, what you say just can't happen (with the code you show). Running the code you show, with print "this is Derived.virtual!" as the body of Derived.virtual, does of course print exactly this string (after the I am in class Derived, blah blah string of course). Your bug must be in some other part of code that you're not showing.Caterwaul
T
5

It isn't impossible -- there is a way around this actually, and you don't have to pass in the function or anything like that. I am working on a project myself where this exact problem came up. Here is the solution:


class Base(): # no need to explicitly derive object for it to work
    attr1 = 'I am in class Base'
    attr2 = 'halb halb'

    def virtual(self):
        print "Base's Method"

    def func(self):
        print "%s, %s" % (self.attr1, self.attr2)
        self.virtual()

class Derived(Base):
    attr1 = 'I am in class Derived'
    attr2 = 'blah blah'

    def __init__(self):
  # only way I've found so far is to edit the dict like this
        Base.__dict__['_Base_virtual'] = self.virtual

    def virtual(self):
        print "Derived's Method"

if __name__ == '__main__':
    d = Derived()
    d.func()

Tallyho answered 28/6, 2010 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.