Right, that's why I said "<font><span style="background-color:rgba(255,255,255,0)">won't access intermediate scopes"...</span></font><br><br>On Thursday, January 2, 2014, Steven D'Aprano wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Thu, Jan 02, 2014 at 02:16:39PM -1000, Guido van Rossum wrote:<br>
> On Thu, Jan 2, 2014 at 3:35 AM, Steven D'Aprano <<a href="javascript:;" onclick="_e(event, 'cvml', 'steve@pearwood.info')">steve@pearwood.info</a>> wrote:<br>
> > I would have guessed that you could get this working with eval, but if<br>
> > there is such a way, I can't work it out.<br>
><br>
> It's trivial if you directly invoke eval():<br>
<br>
That's what I thought too, but I get surprising results with<br>
nonlocals.<br>
<br>
<br>
a = b = "global"<br>
<br>
def test1():<br>
b = c = "nonlocal"<br>
def inner():<br>
d = "local"<br>
return (a, b, c, d)<br>
return inner()<br>
<br>
def test2():<br>
b = c = "nonlocal"<br>
def inner():<br>
d = "local"<br>
c # Need this or the function fails with NameError.<br>
return (eval('a'), eval('b'), eval('c'), eval('d'))<br>
return inner()<br>
<br>
assert test1() == test2() # Fails.<br>
<br>
<br>
test1() returns ('global', 'nonlocal', 'nonlocal', 'local'), which is<br>
what I expect. But test2() returns ('global', 'global', 'nonlocal', 'local'),<br>
which surprises me.<br>
<br>
If I understand what is going on in test2's inner function, eval('b')<br>
doesn't see the nonlocal b so it picks up the global b. (If there is no<br>
global b, you get NameError.) But eval('c') sees the nonlocal c because<br>
we have a closure, due to the reference to c in the previous line.<br>
<br>
If there's a way to get eval('b') to return "nonlocal" without having a<br>
closure, I don't know it. This suggests to me that you can't reliably<br>
look-up a nonlocal from an inner function using eval.<br>
<br>
<br>
--<br>
Steven<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="javascript:;" onclick="_e(event, 'cvml', 'Python-ideas@python.org')">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote><br><br>-- <br>--Guido van Rossum (on iPad)<br>