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:
- I am mostly interested in this on a theoretical level. I would be happy with an answer like "This is not possible because ...", giving some detailed insights about python internals.
- For my concrete problem I have a solution, as the library allows to pass a class which then can do what I want. However, if there would be a way to use the simpler interface of just passing the function which gets bound, I would save many lines of code. (For the interested: This question is derived from the sqlalchemy extension associationproxy and the creator function parameter.)
# 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.