[Tutor] Shadow error

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Thu, 26 Jul 2001 15:32:02 -0700 (PDT)


On Thu, 26 Jul 2001, Christopher Smith wrote:

> Can you help me out here? I tried to create a function that would let me 

No problem; let's take a look.


> get function that would round to the number of desired digits.  This
> is what I tried:
> 
> from random import random as rnd
> 
> l=[rnd() for i in range(3)]
> 
> def dig(n=2):
> 	return lambda x:round(x,n)
> print map(dig(2),l)
> 
> Here's what I got:
> 
> <Untitled Script 2>:5: SyntaxWarning: local name 'n' in 'dig' shadows 
> use of 'n' as global in nested scope 'lambda'
> [0.5, 0.28000000000000003, 0.84999999999999998]


The "problem" lies in the definition here:

> def dig(n=2):
> 	return lambda x:round(x,n)

Python, by default, isn't "lexically scoped": that is, the only variables
that the lambda knows about is 'x'.  Nested functions, then, aren't
allowed to borrow functions from the nester.  To fix this, we could do a
silly trick like this:

###
def dig(n=2):
	return lambda x, n=n:round(x,n)
###

which works on the principle that we're taking advantage of default
arguments.  It is a little ugly, but there are alternatives.



As of Python 2.1, you can get Python to do lexical scoping by using a
funny line:

###
from __future__ import nested_scopes
###

We're using stuff from the future.  *grin* If you put that line in the top
of your file, the warning should disappear.  If you have questions, please
feel free to ask them.