Connecting Tech Pros Worldwide Help | Site Map

can i define a new method at runtime?

Raoul
Guest
 
Posts: n/a
#1: Jul 18 '05
I have a GUI application where I want to assign validation methods to
controls.

If my control myTextBox has a change() event for on change and I want
to make it verify the input is an integer I could do...

def myTextBox.change():
verifyInteger(myTextBox.Value)

def verifyInteger(x):
try:
string.atoi(x.value)
except ValueError :
message(x," needs to be an integer")
x.setFocus()

but i have literally hundreds of these things to do....

I'd like to be able to say somethign like

myTextBox.change = lambda x : verifyInteger(x)

so when i initialize my form i'd like to run through a list that looks
like

[["controlName1","verifyInteger"],["controlName2,"verifyFloat"],["controlName3
"verifyInteger"]

but i can't seem to make this work.

I've tried to use exec("def foo = lambda x: do something....")

but that doesn't seem to work....

Got any ideas ???
Reinhold Birkenfeld
Guest
 
Posts: n/a
#2: Jul 18 '05

re: can i define a new method at runtime?


Raoul wrote:
[color=blue]
> If my control myTextBox has a change() event for on change and I want
> to make it verify the input is an integer I could do...
>
> def myTextBox.change():
> verifyInteger(myTextBox.Value)
>
> def verifyInteger(x):
> try:
> string.atoi(x.value)
> except ValueError :
> message(x," needs to be an integer")
> x.setFocus()
>
> but i have literally hundreds of these things to do....
>
> I'd like to be able to say somethign like
>
> myTextBox.change = lambda x : verifyInteger(x)
>
> so when i initialize my form i'd like to run through a list that looks
> like
>
> [["controlName1","verifyInteger"],["controlName2,"verifyFloat"],["controlName3
> "verifyInteger"][/color]

I'm not a guru, so expect this solution to be bloated ;)

For example, (ab)use a class to build a unit with all the verify-functions:

class Verify(object):
def verify_integer(x): [...]
def verify_float(x): [...]

# Then, iterate over the list:

for pair in list: # list being your example above
control = getattr(__main__, pair[0])
control.changed = eval("lambda self: Verify." + pair[1] + "(self.Value)")
# for this line there MUST be a solution without eval but I don't see it
at the moment

BTW, you should use tuples if the information about the handling
functions is static.

regards, Reinhold

--
Wenn eine Linuxdistribution so wenig brauchbare Software wie Windows
mitbrächte, wäre das bedauerlich. Was bei Windows der Umfang eines
"kompletten Betriebssystems" ist, nennt man bei Linux eine Rescuedisk.
-- David Kastrup in de.comp.os.unix.linux.misc
Ville Vainio
Guest
 
Posts: n/a
#3: Jul 18 '05

re: can i define a new method at runtime?


>>>>> "Raoul" == Raoul <raoulsam@yahoo.com> writes:

Raoul> I have a GUI application where I want to assign validation
Raoul> methods to controls.

Raoul> If my control myTextBox has a change() event for on change
Raoul> and I want to make it verify the input is an integer I
Raoul> could do...

If there is a change method, I assume you need to implement the class
yourself. Why not just subclass the root TextBox class and create a
IntegerTextBox class that has verifyInteger in the change method? Then
you just choose at instantiation time that this particular textbox
needs an integer...

--
Ville Vainio http://tinyurl.com/2prnb
Larry Bates
Guest
 
Posts: n/a
#4: Jul 18 '05

re: can i define a new method at runtime?


You are close. Try something like

def verifyInteger(x):
try:
string.atoi(x.value)
except ValueError :
message(x," needs to be an integer")
x.setFocus()

In a dictionary put keys (controlNames) and
pointers to what function (or method) to call
for that controlName.

verifiers={'controlName1': verifyInteger,
'controlName2': verifyFloat,
...
'controlNameN': veryfySomething}


In your program call the function from the
dictionary as follows:

verifiers['controlName1'](x)
verifiers['controlName2'](x)
....

This works because the result of the getting
verifiers[controlName] is a pointer to a
function instead of a value. This pointer
has a call method, so you can just put the
arguments after it.

HTH,
Larry Bates
Syscon, Inc.

"Raoul" <raoulsam@yahoo.com> wrote in message
news:7b22ae5b.0406181049.479d1a61@posting.google.c om...[color=blue]
> I have a GUI application where I want to assign validation methods to
> controls.
>
> If my control myTextBox has a change() event for on change and I want
> to make it verify the input is an integer I could do...
>
> def myTextBox.change():
> verifyInteger(myTextBox.Value)
>
> def verifyInteger(x):
> try:
> string.atoi(x.value)
> except ValueError :
> message(x," needs to be an integer")
> x.setFocus()
>
> but i have literally hundreds of these things to do....
>
> I'd like to be able to say somethign like
>
> myTextBox.change = lambda x : verifyInteger(x)
>
> so when i initialize my form i'd like to run through a list that looks
> like
>
>[/color]
[["controlName1","verifyInteger"],["controlName2,"verifyFloat"],["controlNam
e3[color=blue]
> "verifyInteger"]
>
> but i can't seem to make this work.
>
> I've tried to use exec("def foo = lambda x: do something....")
>
> but that doesn't seem to work....
>
> Got any ideas ???[/color]


Hung Jung Lu
Guest
 
Posts: n/a
#5: Jul 18 '05

re: can i define a new method at runtime?


raoulsam@yahoo.com (Raoul) wrote:[color=blue]
>
> but i have literally hundreds of these things to do....
>
> I'd like to be able to say somethign like
>
> myTextBox.change = lambda x : verifyInteger(x)
>
> so when i initialize my form i'd like to run through a list that looks
> like
>
> [["controlName1","verifyInteger"],["controlName2,"verifyFloat"],["controlName3
> "verifyInteger"][/color]

def change_Integer(self):
try:
string.atoi(self.value)
except ValueError:
message(...)
self.setFocous()
def change_Currrency(self):
...

dict = {"box1": "Integer", "box2": "Currency"}

import new
for (box_name, box_type) in dict.iteritems():
function_name = 'change_%s' % box_type
f = eval(function_name)
box = getattr(myFrame, box_name)
box.change = new.instancemethod(f, box, box.__class__)

replace eval() by globals() if safety is a concern, or replace by
getattr(...) if functions are defined in modules or classes. (.im_func
maybe needed, anyway, you'll figure out the specifics on your own.)

Hung Jung
Hung Jung Lu
Guest
 
Posts: n/a
#6: Jul 18 '05

re: can i define a new method at runtime?


Ville Vainio <ville@spammers.com> wrote:[color=blue]
> If there is a change method, I assume you need to implement the class
> yourself. Why not just subclass the root TextBox class and create a
> IntegerTextBox class that has verifyInteger in the change method? Then
> you just choose at instantiation time that this particular textbox
> needs an integer...[/color]

This is OK if there are only a few types of boxes. But entry data
types are features, and they tend to grow and become complicated, even
if Regex (regular expression) patterns were used. Besides, the
verification logic is a conceptual unit on its own right, so according
to the AOP (aspect-oriented programming) philosophy, it's best to
group the verification methods together in some "aspect class". There
may be new dimensions to the problem that one may not have foreseen at
the time of design. For instance, localization (currency, dates, usage
of commas and periods, ZIP codes, etc.) Having verification code in
its own hierarchy allows you to make changes more easily and take
advantage of class inheritance for code re-use. Once you have the
verification logic done, you hook it to the widget objects somehow. In
Python, this usually involves some form of metaprogramming. There are
too many ways to do it, and you'll probably not find two people doing
it the same way. Some tools in the arsenal are: using
functions/methods as first class objects and assign them or tweak them
to your heart's content, using the "new" module, using code objects
and "exec" statements, tweaking an existing object's __class__
attribute, implementing/overriding the __getattr__() method in
classes, metaclasses, etc. etc.

regards,

Hung Jung
Jeff Epler
Guest
 
Posts: n/a
#7: Jul 18 '05

re: can i define a new method at runtime?


Something like the untested code below will work, without the need to
"exec" anything.

def verifyInteger(x): ...
def verifyFloat(x): ...
verifiers = {"ControlName1": verifyInteger, "ControlName2": verifyFloat, ....}

class MyTextBox(TextBox):
def __init__(self, controlname, ...):
self.verifyfunc = verifiers[self.controlname]
TextBox.__init__(self, ...)
...
def change(self):
self.verifyfunc(self.value)

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFA1szcJd01MZaTXX0RAizxAJ4lzaIFRv5xeS0+YlD3rK evATT4kACgjbwn
izanXr8+GfuUL9sRfERyi2w=
=12C3
-----END PGP SIGNATURE-----

Closed Thread