The typical way to add functionality to a function is to use a decorator (using the wraps function):
from functools import wraps
def add_message(func):
@wraps
def with_additional_message(*args, **kwargs)
try:
return func(*args, **kwargs)
finally:
print "and here"
return with_additional_message
class A:
@add_message
def test(self):
print "here"
Of course, it really depends on what you're trying to accomplish. I use decorators a lot, but if all I wanted to do was to print extra messages, I'd probably do something like
class A:
def __init__(self):
self.messages = ["here"]
def test(self):
for message in self.messages:
print message
a = A()
a.test() # prints "here"
a.messages.append("and here")
a.test() # prints "here" then "and here"
This requires no meta-programming, but then again your example was probably greatly simplified from what you actually need to do. Perhaps if you post more detail about your specific needs, we can better advise what the Pythonic approach would be.
EDIT: Since it seems like you want to call functions, you can have a list of functions instead of a list of messages. For example:
class A:
def __init__(self):
self.funcs = []
def test(self):
print "here"
for func in self.funcs:
func()
def test2():
print "and here"
a = A()
a.funcs.append(test2)
a.test() # prints "here" then "and here"
Note that if you want to add functions that will be called by all instances of A
, then you should make funcs
a class field rather than an instance field, e.g.
class A:
funcs = []
def test(self):
print "here"
for func in self.funcs:
func()
def test2():
print "and here"
A.funcs.append(test2)
a = A()
a.test() # print "here" then "and here"