Why ClassWithCallable
instance isn't passed to the __call__
function? How can I make that happen?
class Callable:
def __call__(self, *args, **kwargs):
print(self, args, kwargs)
print('Where is `ClassWithCallable` instance?')
class ClassWithCallable:
method = Callable()
instance = ClassWithCallable()
instance.method('some', data='data')
instance.method(instance, 'some', data='data') # ugly :(
Output:
<__main__.Callable object at 0x7f2b4e5ecfd0> ('some',) {'data': 'data'}
Where is `ClassWithCallable` instance?
<__main__.Callable object at 0x7fef7fa49fd0> (<__main__.ClassWithCallable object at 0x7fef7fa49fa0>, 'some') {'data': 'data'}
CodePudding user response:
in order to "bind" self
, you need to implement the descriptor protocol (similar to how an actual method works!)
class Callable:
def __init__(self, inst=None):
self.inst = inst
def __get__(self, instance, owner):
return type(self)(instance)
def __call__(self, *args, **kwargs):
print(self.inst, args, kwargs)
class C:
callable = Callable()
C().callable(1, a=2)
when the attribute is retrieved, it calls the __get__
of your descriptor -- my implementation returns a "bound" version of Callable
where self.inst
is the self
you seek
example output:
$ python3 t.py
<__main__.C object at 0x7f3051529dc0> (1,) {'a': 2}
CodePudding user response:
I am unsure of your actual requirement. But a simple way would be to let method
be a mere reference to a true method:
class ClassWithCallable:
method = Callable.__call__
From that point,
instance = ClassWithCallable()
instance.method('some', data='data')
gives as expected:
<__main__.ClassWithCallable object at 0x0000023542A76548> ('some',) {'data': 'data'}
Where is `ClassWithCallable` instance?