Re: Method behavior for user-created class instances

2008-07-15 Thread crazychimp132
On Jul 15, 9:53 am, "[EMAIL PROTECTED]"
<[EMAIL PROTECTED]> wrote:
> On 15 juil, 01:24, [EMAIL PROTECTED] 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.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method behavior for user-created class instances

2008-07-15 Thread [EMAIL PROTECTED]
On 15 juil, 01:24, [EMAIL PROTECTED] 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)


--
http://mail.python.org/mailman/listinfo/python-list


Re: Method behavior for user-created class instances

2008-07-14 Thread crazychimp132
On Jul 14, 9:04 pm, Larry Bates <[EMAIL PROTECTED]> wrote:
> [EMAIL PROTECTED] 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__().
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method behavior for user-created class instances

2008-07-14 Thread Larry Bates

[EMAIL PROTECTED] 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
--
http://mail.python.org/mailman/listinfo/python-list