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)