Python: Bind an Unbound Method?

This can be done cleanly with types.MethodType. Example:

import types

def f(self): 
    print(self)

class C: 
    pass

meth = types.MethodType(f, C(), C) # Bind f to an instance of C
print(meth) # prints <bound method C.f of <__main__.C object at 0x01255E90>>

This will bind self to handler:

bound_handler = lambda *args, **kwargs: handler(self, *args, **kwargs)

This works by passing self as the first argument to the function. object.function() is just syntactic sugar for function(object).


All functions are also descriptors, so you can bind them by calling their __get__ method:

bound_handler = handler.__get__(self, MyWidget)

Here's R. Hettinger's excellent guide to descriptors.


As a self-contained example pulled from Keith's comment:

def bind(instance, func, as_name=None):
    """
    Bind the function *func* to *instance*, with either provided name *as_name*
    or the existing name of *func*. The provided *func* should accept the 
    instance as the first argument, i.e. "self".
    """
    if as_name is None:
        as_name = func.__name__
    bound_method = func.__get__(instance, instance.__class__)
    setattr(instance, as_name, bound_method)
    return bound_method

class Thing:
    def __init__(self, val):
        self.val = val

something = Thing(21)

def double(self):
    return 2 * self.val

bind(something, double)
something.double()  # returns 42

Creating a closure with self in it will not technically bind the function, but it is an alternative way of solving the same (or very similar) underlying problem. Here's a trivial example:

self.method = (lambda self: lambda args: self.do(args))(self)