Beginners' Question -- Assigning variables in a lambda

Tim Rowe digitig at cix.co.uk
Sun May 28 00:32:00 CEST 2000


In article <m37lchjgri.fsf at atrus.jesus.cam.ac.uk>, mwh21 at cam.ac.uk 
(Michael Hudson) wrote:

Thanks. I'm not really comfortable with either, though. In my version, 
handler will have quite a few keys but two or three actual handlers. Your 
first solution assumes that all keys are handled in essentially the same 
way (sorry, I may have wrongly implied that when I said what get_number() 
does). The second solution involves writing a separate handler for each 
key (ok, so does my failed lambda solution, but it's more compact!) What I 
really want to do is assign one of the few handlers to each key. All the 
handlers will assign to a variable which I would really like to be in the 
local scope of the call, but global scope would do, but they will derive 
the variable in different ways. For example, the one I've shown interprets 
the parameter as a string representation of a number and converts it to a 
numerical representation; another will force the parameter into string 
form.

By the way, I don't mind you asserting on user data. Just so long as you 
catch the resulting AssertError before it gets to the top! (I hadn't even 
noticed Python had assert -- I see it's new in 1.5, but it doesn't seem to 
get much attention in the documentation. Still, another reason Python is 
fast becoming my favourite scripting language!)



> digitig at cix.co.uk (Tim Rowe) writes:
> 
> > Are beginners' questions ok here? (if not, where?)
> 
> Yes.  You might want to try python-help or tutor at python.org, though.
> 
> > After I've done my getopt (or maybe instead, if I can get this to 
> > work) I want to avoid the if/elif/else from hell by having a 
> > dictionary of parameter names and functions, something like:
> > 
> >    handler = {
> >       # Doesn't work!
> >       "b": lambda x: eval("bandwidth = get_number(" + x + ")")
> >       # , ... more here ...
> >       }
> >       
> > (get_number is essentially string.atof with some special handling)
> > then later on do, for example:
> >    handler["b"]("0.23")
> > 
> > and I'd like to call eval("bandwidth = get_number(0.23)") (it seems 
> > to get that far) and so assign 0.23 to bandwidth (it won't do that 
> > bit!)
> > 
> > I suspect my problem is that I need to exec("bandwidth = get_number(" 
> > + x + ")"), but lambda won't take exec.
> > 
> > Is there a sensible way to do what I'm tying to do?
> 
> Not directly, but there are almost certainly sensible ways of
> acheiving your goal.
> 
> One attempt might look like this:
> 
> option2attr = {
>     "b":"bandwidth",
>     ...
> }
> 
> class Settings:
>     def __init__(self):
>         self.bandwith = 9600
>         ...
>     def handle_option(self,opt,val)
>         setattr(self,option2attr[opt],eval(val,{"__builtins__":{}}))
> 
> settings = Settings()
> 
> for k,v in get_options():
>     settings.handle_option(k,v)
> 
> Or similar, but a bit fancier:
> 
> class Settings:
>     option2meth = {
>         "b":"set_bandwidth",
>         ...
>     }
> 
>     def __init__(self):
>         self.bandwith = 9600
>         ...
>     def handle_option(self,opt,val)
>         
> getattr(self,self.option2meth[opt])(eval(val,{"__builtins__":{}}))
>     def set_bandwidth(self,val):
>         assert 300 < val < 100000 # hmm, you shouldn't assert on 
>                                   # user data, but I'm too lazy to
>                                   # change it now...
>         self.bandwidth = val
>     ...
> 
> settings = Settings()
> 
> for k,v in get_options():
>     settings.handle_option(k,v)
> 
> HTH,
> Michael
> 
> -- 
>   There are 'infinite' number of developed artifacts and one cannot
>   develop appreciation  for them all.  It would be all right to not
>   understand something, but it would be imbecilic to put judgements
>   on things one don't understand.               -- Xah, comp.lang.lisp
> 




More information about the Python-list mailing list