Overload a method with a function at runtime

metaprogramming, python

Solution

Don't worry about the self parameter, the function already has that from local scope.

class SomeClass(object):
    def __init__(self):
        def __(arg):
            self.bar(arg)
        self.foo = __
    def foo(self, arg):
        print "foo", arg
    def bar(self, arg):
        print "bar", arg

SomeClass().foo("thing") # prints "bar thing"

When creating an instance (after `__new__`, iirc, but before `__init__`) Python binds all the methods to automagically supply the instance as the first argument. If you're adding a method later then you need to supply the instance manually. As you are defining the function with `self` already in scope you don't need to pass it again.

Python's `new` module is not a solution as it has been deprecated since 2.6. If you want to create a "real" instance method do it with the partial decorator like this:

import functools

class SomeClass(object):
    def __init__(self):
        def __(self, arg):
            self.bar(arg)
        self.foo = functools.partial(__, self)
    def foo(self, arg):
        print "foo", arg
    def bar(self, arg):
        print "bar", arg

SomeClass().foo("thing") # prints "bar thing"

Problem

OK, I'll admit upfront this is a mega kludge and that I could definately implement this better. It's only morbid curiosity that's driving me to find out how I could do this. ``` class SomeClass(object): def __init__(self): def __(self, arg): self.doStuff(arg) self.overLoaded = __ def doStuff(self, string): print string SomeClass().overLoaded("test string") ``` This returns a parameter error because I'm only supplying overLoaded() with one argument instead of two. Is there some magic to tell the interpreter that it's now a method of a class (I tried decorating it with @classmethod, I always understood this to be it's purpose??)

Original source