class derived from dict in eval
Alex Martelli
aleax at aleax.it
Tue Feb 25 11:48:52 EST 2003
Andrew Dalke wrote:
> Alex:
>> def evalWithSpecialDict(expression, specialDict):
>> compiled = compile(expression, '<string>', 'eval')
>> realDict = {}
>> for varname in compiled.co_names:
>> realDict[varname] = specialDict[varname]
>> return eval(compiled, realDict)
>
> Wow! Totally different and much cleaner than my code, which looks
> like
>
> # exception message changes through time
> try:
> {}["QWE"]
> except KeyError, msg:
> msg = str(msg)
> key_start = msg.find("QWE")
> key_end = -(len(msg) - key_start + 3)
Wow -- heroic, really...
> def super_eval(s, d):
> real_d = {}
> while 1:
> try:
> return eval(s, real_d)
> except KeyError, msg:
> key = str(msg)[key_start:key_end]
> real_d[key] = d[k]
>
> (from memory and untested so there may be some mistakes)
Hmmm, one architectural one, I think -- what happens if
d is, say, {'a': 23}, while s is, say, '{}["a"]', which
SHOULD raise a KeyError? I think this will loop forever...
This can be fixed, e.g. by changing the last statement
to:
if key in real_d:
raise
real_d[key] = d[key]
i.e., if the key IS already in the real_d and yet a
KeyError is still raised, then re-raise it, as it just
can't be fixed. This idea might come in handy in some
slightly different context.
> I never even thought of compiling the code to look for the list of
> names. I think I'll rewrite that bit of code now.
>
> Thanks Alex!
You're welcome! I'm slightly surprised I didn't already
post this kind code in the past, put it in the cookbook,
or something like that, but some googling suggests I didn't.
Alex
More information about the Python-list
mailing list