Distinguishing between functions and methods in a decorator.

Arnaud Delobelle arnodel at googlemail.com
Thu Feb 7 13:16:59 EST 2008


On Feb 7, 4:10 pm, Berteun Damman <berteun at NO_SPAMdds.nl> wrote:
> Hello,
>
> I was wondering a bit about the differences between methods and
> functions. I have the following:
>
> def wrap(arg):
>     print type(arg)
>     return arg
>
> class C:
>     def f():
>         pass
>
>     @wrap
>     def g():
>         pass
>
> def h():
>     pass
>
> print type(C.f)
> print type(h)
>
> Which gives the following output:
> <type 'function'>
> <type 'instancemethod'>
> <type 'function'>
>
> The first line is caused by the 'wrap' function of course. I had
> expected the first line to be 'instancemethod' too. So, I would guess,
> these methods of C are first created as functions, and only then become
> methods after they are 'attached' to some classobj. (You can do that
> yourself of course, by saying, for example, C.h = h, then the type of
> C.h is 'instancemethod' too.)
>
> Why does the wrapping occur before the function is 'made' into an
> instancemethod?

Consider this:

>>> class Foo(object):
...     def bar(self): pass
...
>>> Foo.bar
<unbound method Foo.bar>
>>> Foo.__dict__['bar']
<function bar at 0x7d5b0>
>>>

It shows that when Foo.bar is evaluated, a new instancemethod object
is created and that the 'bar' in the dictionary of 'Foo' is forever a
plain function object.  In fact, Foo.bar is equivalent to
Foo.__dict__['bar'].__get__(None, Foo):

>>> Foo.__dict__['bar'].__get__(None, Foo)
<unbound method Foo.bar>
>>>

For more details you can read http://users.rcn.com/python/download/Descriptor.htm.

> The reason for asking is that I would like to differentiate between
> wrapping a function and an instancemethod, because in the latter case,
> the first parameter will be the implicit 'self', which I would like to
> ignore.  However, when the wrapping occurs, the method still looks like
> a function.
>
> Berteun

I think you're better off having a 'wrap' decorator for functions and
a 'wrapmethod' decorator for methods.

HTH

--
Arnaud



More information about the Python-list mailing list