How to bound a method to a instance ?

E

Emmanuel

Hi,


I would like to know how to bound a method to a instance of a class.

One application would be to allow a change in a method after a reload :

module toto :
--------------
class toto:
def method(self):
(...)


main module :
--------------
import toto

a = toto.toto()
a.method() -> does something ...

reload (toto)
now a is not reloaded...

a.method = toto.toto().method
does not work, because a.method would be bounded to a new instance...


Thanks,

Emmanuel...
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Emmanuel said:
main module :
--------------
import toto

a = toto.toto()
a.method() -> does something ...

reload (toto)
now a is not reloaded...

a.method = toto.toto().method
does not work, because a.method would be bounded to a new instance...

It might be best to change the class of a:

reload (toto)
a.__class__ = toto.toto

Then, a.method will automatically become the new method. Of course,
this will also change all other methods of toto, not just method.

If you really want to change only method, you could do

a.__class__.__dict__['method'] = toto.toto.__dict__['method']

That would change just method, but of all instances of the old
definition of toto.toto.

If you really want to change only one method, and only of one
object, you need to use new.instancemethod:

a.method = new.instancemethod(toto.toto.method.im_func, a, a.__class__)

Regards,
Martin
 
E

Emmanuel

Wonderfull !!

I thank you very much for this clear explanation...

Emmanuel

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?= a écrit :
Emmanuel said:
main module :
--------------
import toto

a = toto.toto()
a.method() -> does something ...

reload (toto)
now a is not reloaded...

a.method = toto.toto().method
does not work, because a.method would be bounded to a new instance...

It might be best to change the class of a:

reload (toto)
a.__class__ = toto.toto

Then, a.method will automatically become the new method. Of course,
this will also change all other methods of toto, not just method.

If you really want to change only method, you could do

a.__class__.__dict__['method'] = toto.toto.__dict__['method']

That would change just method, but of all instances of the old
definition of toto.toto.

If you really want to change only one method, and only of one
object, you need to use new.instancemethod:

a.method = new.instancemethod(toto.toto.method.im_func, a, a.__class__)

Regards,
Martin
 
M

Maarten van Reeuwijk

Martin v. Löwis said:
It might be best to change the class of a:

reload (toto)
a.__class__ = toto.toto

Thank you emmanuel for asking this question, I was wondering exactly the
same thing. Is it also possible to override the reload method to make it
(besides reloading) to scan through all namespaces for objects of class
toto.toto and replace their methods automatically? What would that code
look like?

Thanks,

Maarten
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Maarten said:
Thank you emmanuel for asking this question, I was wondering exactly the
same thing. Is it also possible to override the reload method to make it
(besides reloading) to scan through all namespaces for objects of class
toto.toto and replace their methods automatically? What would that code
look like?

In general, it is impossible or atleast very inefficient to do that.
It may be easiest if toto.toto would prepare itself for reloading:

import weakref
try:
weakref.totos
except AttributeError:
weakref.totos = []

class toto:
def __init__(self, args):
weakref.totos.append(weakref.ref(self))
...

def update_totos():
for t in weakref.totos:
t = t()
if t: t.__class__ = toto

def shrink_totos():
totos = []
for t in weakref.totos:
if t(): totos.append(t)
weakref.totos=[]

Then, after reloading toto, invoke toto.update_totos(). From
time to time, invoke weakref.shrink_totos(), to discard unused
weak references.

If you absolutely want to update all objects without preparing
a list earlier, you can use gc.get_objects() to find all containers;
you need to find out which of those are totos. Don't compare the
classes of the objects for identity (o.__class__ is toto.toto), unless
you have a reference of the old class (i.e. before reloading).

Regards,
Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,178
Messages
2,570,955
Members
47,509
Latest member
Jack116

Latest Threads

Top