GeneralBecos
GeneralBecos

Reputation: 2556

Python inheritance in dynamically created classes

I'm trying to use metaclasses to implement the following functionality:

class foo( object ):

    def __init__( self ):
        self.val = 'foo'

    def bar( self ):
        print 'hello world'
        print self.val

f = foo()
f.bar() #prints 'hello world' followed by foo

def newbar( self ):
    super( **?**, self).bar()
    print 'another world!'

fooNew = type('fooNew', (foo,), {'bar':newbar})
n = fooNew()
n.bar() # should print everything in f.bar() followed by 'another world!'

I understand I can use monkey patching to implement my own function newbar. However there is a subtle difference, I want the new bar function to first run the base class bar function and only then run any additional functionality.

How can I do this? or how could I do this better?

Upvotes: 2

Views: 183

Answers (2)

Sven Marnach
Sven Marnach

Reputation: 601559

Using super() to call base class methods has advantages in certain multiple inheritance situations, but disadvantages in most other cases (which is, in 95 % of use cases). So simply don't use super() here, but rather call the base class method directly.

I would go yet another way (provided I'm sure I really want to dynamically create a class). You can define the whole class inside a function and return it:

def class_factory():
    class NewFoo(foo):
        def bar(self):
            foo.bar()
            print 'another world!'
    return NewFoo

Upvotes: 5

Sean Vieira
Sean Vieira

Reputation: 159905

You can change the definition of newbar to return a function instead:

def newbar_factory(cls):
    def newbar(self):
        super(cls, self).bar()
        # Alternately, as Sven points out you could do
        # cls.bar(self)
        print "another world!"

    return newbar

# Use
fooNew = type('fooNew', (foo,), {'bar':newbar_factory(foo)})

There is probably a better way to accomplish the kind of thing you are trying to do - but this should do the trick.

Upvotes: 3

Related Questions