John Machin
1/11/2008 8:23:00 PM
browerg@verizon.net wrote:
> The code that follows is the result of noodling around with switches as a learning tool. I've played with python for a few years, but I'm self-taught, so . . .
>
> Class Switch builds a set of functions. Method switch executes one of them given a value of the switch variable.
>
> My question is, why are modules imported at the top of the program not visible to the functions Switch builds? There is
> no problem when the import is in the function, but I thought initially that imports at the top would be in its globals.
The global namespace of the to-be-exec'ed code is the dictionary that
you supply. That dictionary doesn't contain "math". More comments below.
[snip]
>
> #import math
>
> class Switch(object):
>
> def __init__(self, keys, vals, base):
> self.dictionary = {}
> tmpd = {}
Uncomment the above import, remove the import from your constructed
source code and try
tmpd = {'math': math}
> for i in range(len(vals)):
> func = ''.join([base[0] % keys[i], vals[i], base[1]])
> compile(func, '<stderr>', 'exec')
> exec(func, tmpd)
compile returns a code object, which you are throwing away. Comment out
that statement, and the behaviour of your code will not change. This is
because if the first argument to exec is a string, it is compiled into a
code object.
It's a long time since exec has been documented as a *function*. Why?
Because it isn't:
>>> exec "print 'xxx'"
xxx
>>> exec("print 'xxx'")
xxx
>>> foo = compile
>>> foo
<built-in function compile>
>>> foo = exec
File "<stdin>", line 1
foo = exec
^
SyntaxError: invalid syntax
>>>
What book/tutorial did you get that from?
Cheers,
John