Difference between 'function' and 'method'
castironpi at gmail.com
castironpi at gmail.com
Tue Mar 4 21:30:26 EST 2008
On Mar 4, 8:11 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar> wrote:
> En Tue, 04 Mar 2008 16:45:40 -0200, <castiro... at gmail.com> escribió:
>
> >> > So, to answer your question: what you are decorating are functions,
> >> not
> >> > methods.
>
> >> Can you overload -type-'s decision of what to 'bind'?... whenever it
> >> is it makes it.
>
> >>>> from types import FunctionType, MethodType
> >>>> class A( FunctionType ): pass
> > ...
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in <module>
> > TypeError: type 'function' is not an acceptable base type
>
> Use delegation instead of inheritance. This class is almost
> indistinguishable from a true function (when used as a method):
>
> py> class myfunction(object):
> ... __slots__ = ('func',)
> ... #
> ... def __init__(self, func):
> ... object.__setattr__(self, 'func', func)
> ... #
> ... def __get__(self, instance, owner):
> ... print "__get__ called for",instance
> ... return self.func.__get__(instance, owner)
> ... #
> ... def __getattr__(self, name):
> ... return getattr(self.func, name)
> ... #
> ... def __setattr__(self, name, value):
> ... object.__setattr__(self.func, name, value)
> ...
> py>
> py> class P(object):
> ... def foo(self, x): print 'foo',x
> ... #
> ... @myfunction
> ... def bar(self, x): print 'bar',x
> ...
> py> p = P()
> py> p.foo(1)
> foo 1
> py> p.bar(2)
> __get__ called for <__main__.P object at 0x00A3D650>
> bar 2
> py> P.foo(p, 1)
> foo 1
> py> P.bar(p, 2)
> __get__ called for None
> bar 2
> py> print "p.foo", p.foo, type(p.foo)
> p.foo <bound method P.foo of <__main__.P object at 0x00A3D650>> <type
> 'instancem
> ethod'>
> py> print "p.bar", p.bar, type(p.bar)
> p.bar __get__ called for <__main__.P object at 0x00A3D650>
> <bound method P.bar of <__main__.P object at 0x00A3D650>> __get__ called
> for <__
> main__.P object at 0x00A3D650>
> <type 'instancemethod'>
> py> print set(dir(p.foo))==set(dir(p.bar))
> __get__ called for <__main__.P object at 0x00A3D650>
> True
> py> print "P.foo", P.foo, type(P.foo)
> P.foo <unbound method P.foo> <type 'instancemethod'>
> py> print "P.bar", P.bar, type(P.bar)
> P.bar __get__ called for None
> <unbound method P.bar> __get__ called for None
> <type 'instancemethod'>
> py> print set(dir(P.foo))==set(dir(P.bar))
> __get__ called for None
> True
> py> P.__dict__['foo']
> <function foo at 0x00A3BCB0>
> py> P.__dict__['bar']
> <__main__.myfunction object at 0x00A3D690>
>
> Ok, let's try returning a different thing from __get__: bound method ->
> partial with self already bound; unbound method -> the original function.
>
> py> from functools import partial
> py>
> py> class myfunction2(myfunction):
> ... def __get__(self, instance, owner):
> ... if instance is None:
> ... return self.func
> ... return partial(self.func, instance)
> ...
> py> @myfunction2
> ... def baz(self, x): print 'baz',x
> ...
> py> P.baz = baz
> py> print p.baz
> <functools.partial object at 0x00A3E5A0>
> py> print P.baz
> <function baz at 0x00AB1030>
> py> p.baz(3)
> baz 3
> py> P.baz(p,3)
> baz 3
>
> --
> Gabriel Genellina
I actually don't believe you-- bar is not bound to an instance when P
is initialized... er, instantiated. However, the evidence indicates
my belief mechanism is faulty... and rather conclusively at that.
<moves to acquire new evidence> If P calls __get__( you ), is p a
gotcha?
More information about the Python-list
mailing list