Nested function scope problem

danielx danielwong at berkeley.edu
Mon Jul 24 15:51:56 EDT 2006


Gerhard Fiedler wrote:
> On 2006-07-23 14:53:33, danielx wrote:
>
> > I can't figure out why Josiah's breakLine function won't work either. I
> > know Josiah has had his problem resolved, but I'd still like to know
> > why his func won't work. I'd like to redirect this discussion in that
> > direction, if I may.
>
> I think what happens is this (and this may not be expressed in the proper
> terms for Python): It is possible to read variables from the outer function
> in the inner function. But when trying to write to them, this causes that
> same name to be re-defined in the inner function's scope, making it a
> different variable. Now, in the OP's code, that caused that new variable
> (with scope of the inner function) to be accessed before anything was
> assigned to it.
>
> One obvious way is to not write to the variables from the outer scope, but
> rather return a value from the inner function and assign it in the outer
> function. But it seems there should be a way to be able to write in the
> inner function to variables that are defined in the outer function.
>
>
> >> First point: the nested function only have access to names that exists
> >> in the enclosing namespace at the time it's defined.
> >
> > Coming from lisp, that doesn't make very much sense, and I'm not sure
> > that's true. If you move the def for addTok bellow the lines that
> > initialize the locals of breakLines, you still get the same problem.
>
> The problem there is only secondarily a scope problem. At first it is
> reading a variable (the inner function scope variable tok) before anything
> has been assigned to it. Of course, the real problem is the secondary one:
> that this variable tok is a variable of scope addTok and not of scope
> breakLine.
>
> >> Second point: a nested function cannot rebind names from the enclosing
> >> namespace. Note that in Python, rebinding a name and modifying the
> >> object bound to a name are very distinct operations.
> >
> > I'm not sure that's the problem, because when I ran the debugger, the
> > problem is with the line that says if len(tok), not the one bellow it
> > which says tok = "". Regardless, my above issue seems to be overriding
> > this one.
>
> Yes, but it is the line "tok = ''" that seems to cause tok to be now a
> variable of the inner function's scope (rather than the variable tok of
> breakLine).

OHH! Yes, that sounds like it could be it. Wow, to me, that behavior is
eXtremely unexpected (there's lisp popping up its ugly head again :P).
So you're saying that because an assignment to tok appears later within
the def for addTok, that the line if len(tok) won't try to look in
enclosing local scopes? (If such things even exist...)

Gerhard's reply sounded not so confident. Can we have someone who
"really" knows weigh in on this? Thanks!

>
>
> > After some experimentation, I am completely baffeled as to why
> > breakLine won't work. Here is an example of one of the things I did,
> > which I believe exactly mimics what breakLine does:
> >
> >>>> def outer():
> > ... 	def inner():
> > ... 		if outerLocal:
> > ... 			return "I hear you, 'hello world'."
> > ... 		else:
> > ... 			return "Come again?"
> > ... 	outerLocal = "hello world"
> > ... 	return inner()
> > ...
> >>>> outer()
> > "I hear you, 'hello world'."
> >
> > As I said, I believe the line which sets tok should break (quietly),
> > but not the line which tests tok. My experiment seems to confirm
> > this...
>
> The line that sets tok causes tok to be a different tok from the outer tok
> -- in the whole scope of the assignment.
> 
> Gerhard




More information about the Python-list mailing list