Difference between 'function' and 'method'
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Tue Mar 4 21:11:56 EST 2008
En Tue, 04 Mar 2008 16:45:40 -0200, <castironpi 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
More information about the Python-list
mailing list