Prev: Python Tkinter Linux Repair Question/ Python TCP Socket Example
Next: Why I have to do a deepcopy to the argument?
From: Peter on 15 Jun 2010 18:22 I am puzzled by what appears to be a scope issue - obviously I have something wrong :-) Why does this work: if __name__ == 'main': execfile('test-data.py') print data and yet this doesn't (I get "NameError: global name 'data' not defined"): def X(): execfile('test-data.py') print data where test-data.py is: data = [1,2,3,4] I checked help on execfile and could only find the following (mystifying) sentence: "execfile() cannot be used reliably to modify a functions locals." Thanks Peter
From: MRAB on 15 Jun 2010 19:06 Peter wrote: > I am puzzled by what appears to be a scope issue - obviously I have > something wrong :-) > > Why does this work: > > if __name__ == 'main': > execfile('test-data.py') > print data > > and yet this doesn't (I get "NameError: global name 'data' not > defined"): > > def X(): > execfile('test-data.py') > print data > > where test-data.py is: > > data = [1,2,3,4] > > I checked help on execfile and could only find the following > (mystifying) sentence: > > "execfile() cannot be used reliably to modify a function�s locals." > In the first example 'execfile' is passed globals() by default, which 'test-data.py' modifies. In the second example 'execfile' is passed locals() by default (because it's called from within a function), which 'test-data.py' modifies. However, Python (well, CPython at least), optimises access to locals within functions, which unfortunately means that changes to locals() won't actually affect the function's locals. Here's an example which tries to change the locals: >>> def test(): .... x = 0 .... print "Old value of x:", x .... locals()["x"] = 1 .... print "New value of x:", x .... >>> test() Old value of x: 0 New value of x: 0 Compare this with changing globals: >>> x = 0 >>> print "Old value of x:", x Old value of x: 0 >>> globals()["x"] = 1 >>> print "New value of x:", x New value of x: 1
From: Inyeol Lee on 15 Jun 2010 20:12 On Jun 15, 3:22 pm, Peter <peter.milli...(a)gmail.com> wrote: > I am puzzled by what appears to be a scope issue - obviously I have > something wrong :-) > > Why does this work: > > if __name__ == 'main': > execfile('test-data.py') > print data > > and yet this doesn't (I get "NameError: global name 'data' not > defined"): > > def X(): > execfile('test-data.py') > print data > > where test-data.py is: > > data = [1,2,3,4] > > I checked help on execfile and could only find the following > (mystifying) sentence: > > "execfile() cannot be used reliably to modify a functions locals." > > Thanks > Peter This is due to CPython's static optimization of local name lookup. Dummy 'exec' statement disables this and makes your example work: def X(): exec "None" execfile('test-data.py') print data --inyeol
From: Peter on 15 Jun 2010 20:58 This one seems to do the trick - thanks! :-) On Jun 16, 10:12 am, Inyeol Lee <inyeol....(a)gmail.com> wrote: > On Jun 15, 3:22 pm, Peter <peter.milli...(a)gmail.com> wrote: > > > > > > > I am puzzled by what appears to be a scope issue - obviously I have > > something wrong :-) > > > Why does this work: > > > if __name__ == 'main': > > execfile('test-data.py') > > print data > > > and yet this doesn't (I get "NameError: global name 'data' not > > defined"): > > > def X(): > > execfile('test-data.py') > > print data > > > where test-data.py is: > > > data = [1,2,3,4] > > > I checked help on execfile and could only find the following > > (mystifying) sentence: > > > "execfile() cannot be used reliably to modify a functions locals." > > > Thanks > > Peter > > This is due to CPython's static optimization of local name lookup. > Dummy 'exec' statement disables this and makes your example work: > > def X(): > exec "None" > execfile('test-data.py') > print data > > --inyeol
From: Peter Otten on 16 Jun 2010 05:05
Inyeol Lee wrote: > On Jun 15, 3:22 pm, Peter <peter.milli...(a)gmail.com> wrote: >> I am puzzled by what appears to be a scope issue - obviously I have >> something wrong :-) >> >> Why does this work: >> >> if __name__ == 'main': >> execfile('test-data.py') >> print data >> >> and yet this doesn't (I get "NameError: global name 'data' not >> defined"): >> >> def X(): >> execfile('test-data.py') >> print data >> >> where test-data.py is: >> >> data = [1,2,3,4] >> >> I checked help on execfile and could only find the following >> (mystifying) sentence: >> >> "execfile() cannot be used reliably to modify a function's locals." >> >> Thanks >> Peter > > This is due to CPython's static optimization of local name lookup. > Dummy 'exec' statement disables this and makes your example work: > > def X(): > exec "None" > execfile('test-data.py') > print data > > --inyeol You may also consider the following alternative: def f(): ns = {} execfile('test-data.py', ns) print ns["data"] f() This has the advantage that it can be automatically converted to Python 3. Peter |