sj26's solution is a good one. Another alternative, if you want to set up a method that can be overloaded with any user-supplied function or with another of the object's methods, is build a custom descriptor. This descriptor can be used as a decorator (analogous to @classmethod or @staticmethod); and it allows you to store a function in an instance's dictionary, and returns it as a method:
import types
class overloadable(object):
def __init__(self, func):
self._default_func = func
self._name = func.__name__
def __get__(self, obj, type=None):
func = obj.__dict__.get(self._name, self._default_func)
return types.MethodType(func, obj, type)
def __set__(self, obj, value):
if hasattr(value, 'im_func'): value = value.im_func
obj.__dict__[self._name] = value
def __delete__(self, obj):
del obj.__dict__[self._name]
Now we can just decorate a function with "@overloadable":
class SomeClass(object):
def doStuff(self, string):
print 'do stuff:', string
@overloadable
def overLoaded(self, arg):
print 'default behavior:', arg
And it'll just do the right thing when we overload it for a given instance:
>>> sc = SomeClass()
>>> sc.overLoaded("test string") # Before customization
default behavior: test string
>>> sc.overLoaded = sc.doStuff # Customize
>>> sc.overLoaded("test string")
do stuff: test string
>>> del sc.overLoaded # Revert to default behavior
>>> sc.overLoaded("test string")
default behavior: test string