Nested function scope problem

Gerhard Fiedler gelists at gmail.com
Sun Jul 23 15:40:07 EDT 2006


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). 


> 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