Search code examples
pythonclassmethodsbind

How to bind a function to an object?


Consider this code:

class SomeClass:
    def __init__(self, i):
        self.i = i

    def some_method(self):
        def returned_method(self, new_i):
            self.i = new_i
        return returned_method

some_obj = SomeClass(5)
some_obj.some_method()(6)
print(some_obj.i)

It ends with an exception:

Traceback (most recent call last):
  File "./prog.py", line 11, in <module>
TypeError: returned_method() missing 1 required positional argument: 'new_i'

Clearly, the method returned by some_method is unbound. It doesn't get some_obj as its first argument.

How to bind returned_method in some_method to self?


Solution

  • returned_method isn't a method; it's an ordinary function. There's no need to declare it as taking two arguments.

    def some_method(self):
        def _(new_i):
            self.i = new_i
        return _
    

    _ (no need to give it any particular name) doesn't need self as an argument, because it's a closure over the argument passed to some_method.

    It gets used the same way as before:

    some_obj = SomeClass(5)
    some_obj.some_method()(6)
    print(some_obj.i)