Reputation: 2556
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
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
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