On Jul 14, 9:04 pm, Larry Bates <larry.ba...@websafe.com`wrote:
crazychimp...@gmail.com wrote:
Greetings.
I am looking for a way to achieve method behavior for a class I
created. That is, it has a __call__ method, so can be called like a
function. But I also want it to be treated as a method when it appears
in a class body.
Eg.
class foo:
def __call__(self, inst): pass
class bar:
meth = foo()
such that bar().meth() will not raise an exception for too few
arguments (because the inst argument in foo.__call__ is implicitly set
to the bar instance). I know this has to do with writing the __get__
method of foo, but I am wondering if there is perhaps some class I can
just inherit from to get the proper __get__, which behaves identically
to that of regular Python functions. The need for this arises out of
the implementation of a function decorator as a class.
Thanks.
While it is not clear "why" you would want this, I believe this works.
If not, take a look at staticmethods or classmethods, they might work for you.
>>class foo(object):
... def __call__(self, inst):
... print "foo.__call__", inst
...
>>class bar:
... def __init__(self):
... self.foo = foo()
... self.meth = self.foo.__call__
...
>>b = bar()
>>b.meth(1)
foo.__call__ 1
-Larry
This doesn't work for me. I have a class which is used to decorate
functions, returning a callable object in the place of the original
function. So, instances of this class must be able to be used anywhere
a function would be used, and this means getting method behavior when
it is used in a class body.
A working implementation would be (in 3.0):
from functools import partial
from abc import ABCMeta, abstractmethod
class method_behavior(metaclass = ABCMeta):
def __get__(self, instance, owner):
if instance is None:
return self.__call__
return partial(self.__call__, instance)
@abstractmethod
def __call__(): pass
Then, any decorator class can inherit from it:
class foo(method_behavior):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwds):
print("calling decorated func")
return self.func(*args, **kwds)
Then, we can decorate a function with foo (via @foo) and it will work
either inside a class body or outside, it works everywhere an
undecorated function would work, eg.:
@foo
def bar():
print('bar')
class baz:
@foo
def bar(self):
print('bar')
What I am asking is whether there is a way to directly inherit method
behavior, instead of inexactly rewriting it as I did in
method_behavior.__get__().