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

Attaching functions to objects as methods

P: n/a
Python is a crazy language when it comes to object versatility. I know
I can do:
>>class test:
.... def __init__(self):
.... pass
>>x = test()
def fun():
.... print "fun"
>>x.fun = fun
x.fun()
fun
>>>
However, experimenting shows that these attached functions are not
bound to the object. They do not accept the 'self' parameter. I want to
know how one goes about doing that. How do I bind a function to an
object to act as if it were a method? It looks like the classmethod()
built-in looks *similar* to what I want to do, but not quite.

Any help would be awesome =-)

Jul 7 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
tac-tics wrote:
Python is a crazy language when it comes to object versatility. I know
I can do:
>>>class test:
... def __init__(self):
... pass
>>>x = test()
def fun():
... print "fun"
>>>x.fun = fun
x.fun()
fun

However, experimenting shows that these attached functions are not
bound to the object. They do not accept the 'self' parameter. I want to
know how one goes about doing that. How do I bind a function to an
object to act as if it were a method?
Functions are descriptors[1], and their __get__ method is used to bind
them to a particular instance::
>>class test(object):
... def __init__(self):
... pass
...
>>x = test()
def fun(self):
... print "fun", self
...
>>x.fun = fun.__get__(x, test)
x.fun()
fun <__main__.test object at 0x00E6D730>

Note that calling __get__ returns a bound method, and that method can be
bound to an instance or a class depending on the parameters of __get__::
>>fun.__get__(x, None)
<bound method ?.fun of <__main__.test object at 0x00E74510>>
>>fun.__get__(x, test)
<bound method test.fun of <__main__.test object at 0x00E74510>>
>>fun.__get__(None, test)
<unbound method test.fun>

[1] http://users.rcn.com/python/download/Descriptor.htm

STeVe
Jul 7 '06 #2

P: n/a
Functions are descriptors[1], and their __get__ method is used to bind
them to a particular instance::
Thank you muchly.

Jul 8 '06 #3

P: n/a
On 8/07/2006 9:29 AM, tac-tics wrote:
Python is a crazy language when it comes to object versatility. I know
I can do:
>>>class test:
... def __init__(self):
... pass
>>>x = test()
def fun():
... print "fun"
>>>x.fun = fun
x.fun()
fun

However, experimenting shows that these attached functions are not
bound to the object. They do not accept the 'self' parameter. I want to
know how one goes about doing that. How do I bind a function to an
object to act as if it were a method? It looks like the classmethod()
built-in looks *similar* to what I want to do, but not quite.

Any help would be awesome =-)
Call me crazy, but wasn't this discussed in a thread only a few days ago?

Injecting a method into a class, so that even already-created instances
have that method, is trivial:
>>class K(object):
.... pass
....
>>def fun(self, arg):
.... print "fun"
.... self.frob = arg
....
>>o = K()
K.methc = fun
o.methc("xyz")
fun
>>o.frob
'xyz'
>>>
Injecting a "private" method into a particular instance is not much more
complicated:
>>def own(self, arg):
.... print "own"
.... self.ozz = arg
....
>>p = K()
import types
p.metho = types.MethodType(own, p)
p.metho("plugh")
own
>>p.ozz
'plugh'
>>o = K()
o.metho("xyzzy")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'K' object has no attribute 'metho'
>>>
and no __makeyoureyesbleed__ __doubleunderscoremessingabout__ required :-)

Cheers,
John
Jul 8 '06 #4

P: n/a
Experimenting, I found that
>>x.fun = lambda: fun(x)
works as well. Any comments on this way?

Jul 8 '06 #5

P: n/a
On 8/07/2006 11:01 AM, tac-tics wrote:
Experimenting, I found that
>>>x.fun = lambda: fun(x)

works as well. Any comments on this way?
Appears to work. Less typing for a no-argument method, but you need to
specify the argument list *twice* compared with *zero* times with the
types.MethodType way of doing it.
>>x=K()
x.metho = lambda(a): own(x, a)
x.metho('abcde')
own
>>x.ozz
'abcde'
>>>
Jul 8 '06 #6

P: n/a
John Machin wrote:
Injecting a "private" method into a particular instance is not much more
complicated:
>>def own(self, arg):
... print "own"
... self.ozz = arg
...
>>p = K()
>>import types
>>p.metho = types.MethodType(own, p)
>>p.metho("plugh")
own
>>p.ozz
'plugh'
>>o = K()
>>o.metho("xyzzy")
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'K' object has no attribute 'metho'
>>>

and no __makeyoureyesbleed__ __doubleunderscoremessingabout__ required :-)
=)

But of course you have to import a module instead. I'm not a huge fan of
the types module because it's generally unnecessary, and I'm not
particularly afraid of double-underscores as I write a lot of __init__
methods. ;-)

To the OP: regardless of which solution you eventually go with, it's
definitely worth understanding how descriptors_ work. New-style classes
wouldn't work without them.

... _descriptors: http://users.rcn.com/python/download/Descriptor.htm

STeVe
Jul 8 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.