eval function
Duncan Booth
duncan at NOSPAMrcp.co.uk
Thu Apr 24 08:38:20 EDT 2003
Franck Bui-Huu <Franck.BUI-HUU at gemplus.com> wrote in
news:mailman.1051185097.26743.python-list at python.org:
> but eval seems to not use __getitem__ method of my_dict object because
> "using my_dict" is not printed.
> How can I print "using my_dict" when calling eval function ?
You can't. See http://www.python.org/2.2.2/descrintro.html
"Unifying types and classes in Python 2.2" by Guido van Rossum which
explains:
> We can also use the new type in contexts where classic only allows
> "real" dictionaries, such as the locals/globals dictionaries for the
> exec statement or the built-in function eval():
>
> >>> print a.keys()
> [1, 2]
> >>> exec "x = 3; print x" in a
> 3
> >>> print a.keys()
> ['__builtins__', 1, 2, 'x']
> >>> print a['x']
> 3
> >>>
>
> However, our __getitem__() method is not used for variable access by
> the interpreter:
>
> >>> exec "print foo" in a
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "<string>", line 1, in ?
> NameError: name 'foo' is not defined
> >>>
>
> Why doesn't this print 0.0? The interpreter uses an internal function
> to access the dictionary, which bypasses our __getitem__() override. I
> admit that this can be a problem (although it is only a problem in
> this context, when a dict subclass is used as a locals/globals
> dictionary); it remains to be seen if I can fix this without
> compromising performance in the common case.
A workaround which might work for you would be to compile the expression
first (using the 'compile' builtin) and then check the co_names attribute
of the code object. Then you need to build a real dictionary with just
those names that can be accessed by the expression. This won't, of course,
help if your expressions depend on short circuiting logical operators.
>>> c = compile('1+x', '!', 'eval')
>>> c.co_names
('x',)
>>> eval(c, {'x':3})
4
>>>
--
Duncan Booth
duncan at rcp.co.uk int month(char
*p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
More information about the Python-list
mailing list