(By the way, you misspelled __init__.)
The correct way to add methods to an instance is with the
instancemethod() function.
class Parrot:
def __init__(self):
import new
# define a function
def method_dynamic(self, *args):
args.insert(0, "hello, it's me!")
return self.method_static(*args)
# convert it into an instance method
method = new.instancemethod(function, self, self.__class__)
# add it to self
self.method_dynamic = method
def method_static(self, text):
return text
And here is how I use it:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: class Parrot has no attribute 'method_dynamic'
BUT, having said all that, are you sure this is what you want to do? This
is probably a better way to get the same results:
class Parrot:
def __init__(self):
self.text = "hello, it's me!"
def method_dynamic(self):
return self.method_static(self.text)
def method_static(self, text):
return text
Earlier in the thread, you said you wanted a CLASS method, which is very
different. You can use the classmethod built-in function (no need to
import new) to create class methods:
class Parrot:
def method_dynamic(cls):
return cls.method_static(cls(), "hello it's me")
# or alternatively cls().method_static("hello it's me")
method_dynamic = classmethod(method_dynamic)
def method_static(self, text):
return text
Note: if you are using recent versions of Python, instead of saying
"method = classmethod(method)" AFTER the block, you can use a decorator
before the block.
Making method_dynamic a class method and calling an instance method is not
a good way of doing things, since the class method has to create a new
instance before calling method_static, only to throw it away afterwards.
That is wasteful and could be very expensive.
A better way is to change your class so that method_static is a class
method too, especially since it doesn't use self:
class Parrot:
@classmethod
def method_dynamic(cls):
return cls.method_static("hello it's me")
@classmethod
def method_static(cls, text):
return text
(Actually, since method_static doesn't even use the class, you could use
staticmethod instead of classmethod. Remember to remove the "cls" argument.)
Hope this helps,
Thanks everybody for your responses. I know my terminology isn't
quite exact. Hopefully that didn't confuse you too much. I used that
example hoping to simplify the question. As you'll see below, it
takes more if I have to explain the entire story.
Of all the answers, I think the new.instancemethod is most
appropriate. I'll try to explain:
With a PythonCard application, if you want to have a button, normally
you use the layout editor which creates a dictionary representing the
button, and you would have a function for each of the events it has to
handle. For instance, a simple one button ap might look like this:
#!/usr/bin/python
"""
__version__ = "$Revision: 1.6 $"
__date__ = "$Date: 2004/08/17 19:46:06 $"
"""
from PythonCard import model
rsrc = {'application':{'type':'Application',
'name':'Minimal',
'backgrounds': [
{'type':'Background',
'name':'bgMin',
'title':'Minimal PythonCard Application',
'size'

200, 100),
'components': [
{'type':'Button', 'name':'Button1', 'position'

5, 35),
'label':'Button1'},
] # end components
} # end background
] # end backgrounds
} }
class Minimal(model.Background):
def on_initialize(self, event):
pass
def on_Button1_mouseClick(self, event):
print "Clicked Button1"
if __name__ == '__main__':
app = model.Application(Minimal, None, rsrc)
app.MainLoop()
Notice that the event handler for mouseClick to Button1 is done via
the function on_Button1_mouseClick. This is very simple and works
great - until you try to create the button on the fly.
Creating the button itself is no problem. You simply do a:
self.components['Button1'] = {'type':'Button',
'name':'Button1',
'position'

5, 35),
'label':'Button1'}
But then how do I create the on_Button1_mouseClick function? With the
application I have to come up with, I have a tree on the left, and
then depending which branch the user clicks, I have to create various
controls on the right. So, it becomes some what of a nightmare for me
(since I have lots of branches and they are all quite different).
Each time the use click a branch, I have to create the buttons, data
entry-fields, and so forth on the fly - along with all of the
functions to handle them.
This is what I came up with so far (before reading your messages):
#!/usr/bin/python
"""
__version__ = "$Revision: 1.6 $"
__date__ = "$Date: 2004/08/17 19:46:06 $"
"""
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
} }
class Minimal(model.Background):
def on_initialize(self, event):
return
nButtons = 7
text="class MinimalChild(Minimal):"
text += "\n\t" + "def on_initialize(self, event):"
text += "\n\t" + "\tMinimal.on_initialize(self,event)"
for iButton in xrange(nButtons):
name = "Button"+str(iButton+1)
text += "\n\t" + "\tself.components['"+name+"'] = {" +\
"'type':'Button', " +\
"'name':'"+name+"', " +\
"'label':'"+name+"', "+\
"'position'

5, "+str(35+iButton*30)+")}"
if iButton!=nButtons-1:
text += "\n\t" + "def on_"+name+"_mouseClick(self, event):"
exec(text)
if __name__ == '__main__':
app = model.Application(MinimalChild, None, rsrc)
app.MainLoop()
With this approach, each time I click a button, a new one gets
created, along with a new handler for mouseClick of that new button.
Now, knowing the new.instancemethod way, may be I can simplify the
above somewhat and improve the efficiencies but I still don't see how
one can do it without using the exec function.
Regards,