Adding method to a class on the fly
John Henry
john106henry at hotmail.com
Sat Jun 23 15:31:39 EDT 2007
On Jun 23, 10:56 am, Steven D'Aprano
<s... at REMOVE.THIS.cybersource.com.au> wrote:
> On Sat, 23 Jun 2007 09:06:36 -0700, John Henry wrote:
>
> >> > But then how do I create the on_Button1_mouseClick function?
>
> >> That depends on what it is supposed to do, but in general you want a
> >> factory function -- a function that returns functions. Here's a simple
> >> example:
>
> > <snip>
>
> > Steven,
>
> > May be I didn't explain it clearly: the PythonCard package expects to
> > see a function by the name of on_Button1_mouseClick. I don't do
> > anything to register the callback function. The package assumes that
> > there is a function by that name whenever I create a button named
> > Button1. So, if I don't use exec, how can I create a function by that
> > exact name?
>
> def mouseclick_factory(name):
> def function(self, event):
> print "You clicked '%s'." % name
> function.name = "on_%s_mouseClick" % name
> return function
>
> class Parrot:
> def __init__(self, name):
> function = mouseclick_factory(name) # as before
> method = new.instancemethod(function, self, self.__class__)
> setattr(self, function.name, method)
>
> And here it is in action:
>
> >>> p = Parrot("Button1")
> >>> p.on_Button1_mouseClick("event")
>
> You clicked 'Button1'.
>
> --
> Steven.
Wouldn't it be nice if it works right away? :=)
I tried the above method and this is what I have:
#!/usr/bin/python
"""
__version__ = "$Revision: 1.6 $"
__date__ = "$Date: 2004/08/17 19:46:06 $"
"""
import new
from PythonCard import model
rsrc = {'application':{'type':'Application',
'name':'Minimal',
'backgrounds': [
{'type':'Background',
'name':'bgMin',
'title':'Minimal PythonCard Application',
'size':(200, 300),
'components': [
] # end components
} # end background
] # end backgrounds
} }
def mouseclick_factory(parent, name):
id_num=int(name[-1:])
parent.components[name] = {'type':'Button',
'name':name,
'label':name,
'position':(5, 5+id_num*30),
'text':name}
def function(self, event):
print "You clicked '%s'." % name
function.name = "on_%s_mouseClick" % name
return function
class Minimal(model.Background):
def on_initialize(self, event):
self.components['field1'] =
{'type':'TextField','name':'field1','position':(5, 5),'size':(150,
-1),'text':'Hello PythonCard'}
name = "Button1"
function = mouseclick_factory(self, name) # as before
method = new.instancemethod(function, self, self.__class__)
setattr(self, function.name, method)
if __name__ == '__main__':
app = model.Application(Minimal, None, rsrc)
app.MainLoop()
When I click on the button, nothing happens. However, if I call the
function directly (like right after the setattr line:
self.on_Button1_mouseClick(event)
it works fine but PythonCard isn't calling this function when I
clicked on the button.
More information about the Python-list
mailing list