EDIT: I extended the example to show the more complex case that I was talking about before. Thanks for the feedback in the comments.
Some more context:
# mylib.py
from typing import Callable
class C:
def __init__(self, foo: Callable):
self.foo = foo
def __get__(self, instance, owner):
# simplified
return CConcrete(self.foo)
class CConcrete:
foo: Callable
def __init__(self, foo: Callable):
self.foo = foo
def bar(self):
return self.foo()
# main.py
from mylib import C
def my_foo(self):
return True if self else False
class House:
window = C(my_foo)
my_house = House()
print(my_house.window.bar())
This code gives the error
my_foo() missing 1 required positional argument: 'self'
How can I get my_foo
be called with self
without changing the class C itself?
The point is that a class like this exists in a library, so I can't change it.
In fact it's even more complicated, as foo
gets passed down and the actual object where bar
exists and calls self.foo
is not C
anymore. So the solution can also not include assigning something to c
after creation, except it would also work for the more complex case described.
You can bind the method to the instance manually, since it won't be living in the class __dict__
:
self.foo = foo.__get__(self)
This is assuming you don't want to monkeypatch the entire class. If you do, assign c.foo = my_foo
instead of passing to the instance initializer.
You could also conceivably use inheritance:
class C(C):
def __init__(self):
super().__init__(self.foo)
def foo(self):
return True