[Tutor] Class and Scope Question
Karl Pflästerer
sigurd at 12move.de
Fri May 6 14:44:07 CEST 2005
On 6 Mai 2005, tim at johnsons-web.com wrote:
>
> The following test script is kind of got me baffled:
>#!/usr/local/bin/python
> class Eval:
> def __getitem__(self,key):
> return eval(key)
>##def test():
>## i = 100
>## b = ["My", "name", "is", "Tim"]
>## test = "this is number %(str(i))s for a test %(' '.join(b))s"
>## s = test % Eval()
>## print s
>##test()
> i = 100
> b = ["My", "name", "is", "Tim"]
> test = "this is number %(str(i))s for a test %(' '.join(b))s"
> print test % Eval()
>## ============================================================
> Running this gives me the following :
> [tim at linus baker]$ python test.py
> this is number 100 for a test My name is Tim
>## cool!
> Now if I comment out the last four lines and uncomment
> the previous 7, I get the following error message:
> [tim at linus baker]$ python test.py
> Traceback (most recent call last):
> File "test.py", line 11, in ?
> test()
> File "test.py", line 9, in test
> s = test % Eval()
> File "test.py", line 4, in __getitem__
> return eval(key)
> File "<string>", line 0, in ?
> NameError: name 'i' is not defined
>## It's been a lloooonngg day. What am I missing here?
> Explanation and solution is no doubt going to further edify
> me about python.
If you look in the Python reference manual under
'Execution model -> Naming and binding -> Interaction with dynamic features'
you will find the following paragraph:
,----
| The `eval()', `execfile()', and `input()' functions and the `exec'
| statement do not have access to the full environment for resolving
| names. Names may be resolved in the local and global namespaces of the
| caller. Free variables are not resolved in the nearest enclosing
| namespace, but in the global namespace.(1) The `exec' statement and the
| `eval()' and `execfile()' functions have optional arguments to override
| the global and local namespace. If only one namespace is specified, it
| is used for both.
|
| ---------- Footnotes ----------
|
| (1) This limitation occurs because the code that is executed by these
| operations is not available at the time the module is compiled.
`----
So you had a free variable `i' which was in your first example found in
the global namespace but in your second example it existed only in the
local namespace. So it wasn't found by `eval'. You could write your
class definition so that you call eval with the correct environment.
E.g. :
class Eval (object):
def __init__(self, Globals = globals(), Locals = locals()):
self.Globals = Globals
self.Locals = Locals
def __getitem__(self,key):
return eval(key, self.Globals, self.Locals)
Then your function definition could become:
def test():
i = 100
b = ["My", "name", "is", "Tim"]
test = "this is number %(str(i))s for a test %(' '.join(b))s"
s = test % Eval(Locals=locals())
print s
Karl
--
Please do *not* send copies of replies to me.
I read the list
More information about the Tutor
mailing list