By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,404 Members | 1,074 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,404 IT Pros & Developers. It's quick & easy.

Functions, callable objects, and bound/unbound methods

P: n/a
If I do this:

def f(self): print self

class c1: pass

setattr(c1, 'm1', f)

Then f is automagically transmogrified into the appropriate sort of
method depending on how it is used:
>>c1.m1
<unbound method c1.f>
>>c1().m1
<bound method c1.f of <__main__.c1 instance at 0x51e738>>
>>c1().m1()
<__main__.c1 instance at 0x51ec60>

Note that m1 gets passed a self argument.

The same automatic transmogrification does not happen if I use an
callable instance instead of an actual function object:

class callable:
def __call__(self, *args, **kw): return args, kw
>>setattr(c1, 'm2', callable())
c1.m2
<__main__.callable instance at 0x51e738>
>>c1().m2
<__main__.callable instance at 0x51e738>
>>c1().m2()
((), {})

Note that no selfarg has been passed to m2.

The reason I want to do this is that I want to implement a trace
facility that traces only specific class methods. I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that to
be an instance of a callable class instead of a function is that I need
a place to store the old value of the method so I can restore it, and I
don't want to start building a global data structure because that gets
horribly ugly, and a callable class is the Right Thing -- if there's a
way to actually make it work.

Is there? I tried the obvious things (like making callable inherit from
function, and adding im_func and im_self attribuetes) but they didn't
work.

Thanks,
rg
Dec 1 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Ron Garret <rN*******@flownet.comwrote:
I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that
to be an instance of a callable class instead of a function is that I
need a place to store the old value of the method so I can restore it,
and I don't want to start building a global data structure because
that gets horribly ugly, and a callable class is the Right Thing -- if
there's a way to actually make it work.

Is there? I tried the obvious things (like making callable inherit
from function, and adding im_func and im_self attribuetes) but they
didn't work.
Read "Functions and Methods" in
http://users.rcn.com/python/download/Descriptor.htm

You need to implement a __get__ method on your class.
Dec 1 '06 #2

P: n/a
Duncan Booth wrote:
Ron Garret <rN*******@flownet.comwrote:
I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that
to be an instance of a callable class instead of a function is that I
need a place to store the old value of the method so I can restore it,
and I don't want to start building a global data structure because
that gets horribly ugly, and a callable class is the Right Thing -- if
there's a way to actually make it work.

Is there? I tried the obvious things (like making callable inherit
from function, and adding im_func and im_self attribuetes) but they
didn't work.

Read "Functions and Methods" in
http://users.rcn.com/python/download/Descriptor.htm

You need to implement a __get__ method on your class.
See also

http://groups.google.com/group/comp....503c5b9c66226e

for an example and some discussion.

Michele Simionato

Dec 1 '06 #3

P: n/a
Ron Garret wrote:
The reason I want to do this is that I want to implement a trace
facility that traces only specific class methods. I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that to
be an instance of a callable class instead of a function is that I need
a place to store the old value of the method so I can restore it, and I
don't want to start building a global data structure because that gets
horribly ugly, and a callable class is the Right Thing -- if there's a
way to actually make it work.
If the only reason for a callable class is to save a single value (the
original function), you could instead store it as an attribute of the
wrapper function.

Kent
Dec 1 '06 #4

P: n/a
Ron Garret wrote:
The reason I want to do this is that I want to implement a trace
facility that traces only specific class methods. I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that to
be an instance of a callable class instead of a function is that I need
a place to store the old value of the method so I can restore it, and I
don't want to start building a global data structure because that gets
horribly ugly, and a callable class is the Right Thing -- if there's a
way to actually make it work.
If the only reason for a callable class is to save a single value (the
original function), you could instead store it as an attribute of the
wrapper function.

Kent
Dec 1 '06 #5

P: n/a
In article <45**************@kentsjohnson.com>,
Kent Johnson <ke**@kentsjohnson.comwrote:
Ron Garret wrote:
The reason I want to do this is that I want to implement a trace
facility that traces only specific class methods. I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that to
be an instance of a callable class instead of a function is that I need
a place to store the old value of the method so I can restore it, and I
don't want to start building a global data structure because that gets
horribly ugly, and a callable class is the Right Thing -- if there's a
way to actually make it work.

If the only reason for a callable class is to save a single value (the
original function), you could instead store it as an attribute of the
wrapper function.
I considered that, and I may yet fall back on it, but 1) I wanted to
understand how these things worked and 2) I need a way to tell when a
method has been traced, and isinstance(method, tracer) seems less
hackish to me than hasattr(method, 'saved_function').

rg
Dec 1 '06 #6

P: n/a
In article <11**********************@j44g2000cwa.googlegroups .com>,
"Michele Simionato" <mi***************@gmail.comwrote:
Duncan Booth wrote:
Ron Garret <rN*******@flownet.comwrote:
I want to say:
>
trace(c1.m1)
>
and have c1.m1 be replaced with a wrapper that prints debugging info
before actually calling the old value of m1. The reason I want that
to be an instance of a callable class instead of a function is that I
need a place to store the old value of the method so I can restore it,
and I don't want to start building a global data structure because
that gets horribly ugly, and a callable class is the Right Thing -- if
there's a way to actually make it work.
>
Is there? I tried the obvious things (like making callable inherit
from function, and adding im_func and im_self attribuetes) but they
didn't work.
Read "Functions and Methods" in
http://users.rcn.com/python/download/Descriptor.htm

You need to implement a __get__ method on your class.

See also

http://groups.google.com/group/comp....d/d691240a5cfe
bcdf/93503c5b9c66226e?lnk=gst&q=simionato+subclassing+F unctionType&rnum=1&hl=e
n#93503c5b9c66226e

for an example and some discussion.

Michele Simionato
Thanks!

rg
Dec 1 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.