Method behavior for user-created class instances

crazychimp132 at gmail.com crazychimp132 at gmail.com
Tue Jul 15 12:18:20 EDT 2008


On Jul 15, 9:53 am, "bruno.desthuilli... at gmail.com"
<bruno.desthuilli... at gmail.com> wrote:
> On 15 juil, 01:24, crazychimp... at 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.
>
> You need to implement the descriptor protocol the same way the
> function type do.
>
> import types
>
> class Foo(object):
>     def __call__(self, instance):
>         print "%s - %s" % (self, instance)
>
>     def __get__(self, instance, cls):
>         return types.MethodType(self, instance, cls)
>
> class Bar(object):
>     foo = Foo()
>
> b = Bar()
> b.foo()
>
> > 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.
>
> Extending types.FunctionType doesn't work OOTB (there's some
> incompatibility wrt/ metaclasses)

Thanks, this got me started in writing it for 3.0. There are no more
unbound methods in 3.0, so a check for whether instance is None is
necessary to give the right behavior. Here is the final implementation
I came up with:

from abc import ABCMeta, abstractmethod
from functools import update_wrapper
from types import MethodType

class decorator(metaclass = ABCMeta):
    def __init__(self, function):
        update_wrapper(self, function)
        self.function = function

    def __get__(self, instance, cls):
        if instance is None:
            return self
        return MethodType(self, instance)

    @abstractmethod
    def __call__(): pass

To use it, write a class that inherits decorator and overrides
__call__, probably doing something with self.function.



More information about the Python-list mailing list