Nested function scope problem
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Sat Jul 22 15:20:32 EDT 2006
Josiah Manson a écrit :
> I found that I was repeating the same couple of lines over and over in
> a function and decided to split those lines into a nested function
> after copying one too many minor changes all over. The only problem is
> that my little helper function doesn't work! It claims that a variable
> doesn't exist. If I move the variable declaration, it finds the
> variable, but can't change it. Declaring the variable global in the
> nested function doesn't work either.
>
> But, changing the variable in the containing scope is the whole purpose
> of this helper function.
>
> I'm new to python, so there is probably some solution I haven't
> encountered yet. Could you please suggest a nice clean solution? The
> offending code is below. Thanks.
>
> def breakLine(s):
> """Break a string into a list of words and symbols.
> """
> def addTok():
> if len(tok) > 0:
if tok:
An empty sequence evals to False in a boolean context.
> ls.append(tok)
> tok = ''
>
First point: the nested function only have access to names that exists
in the enclosing namespace at the time it's defined.
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.
Third point : functions modifying their environment this way are usually
considered bad form.
Here's a possible solution - but note that there are probably much
better ways to get the same result...
def breakline(line):
"""Break a string into a list of words and symbols."""
class TokenList(list):
def append(self, token):
if token:
list.append(self, token)
return ''
tokens = TokenList()
token = ''
splitters = '?()&|:~,'
whitespace = ' \t\n\r'
specials = splitters + whitespace
for char in line:
if char in specials:
token = tokens.append(token)
if char in splitters:
tokens.append(char)
else:
token += char
tokens.append(token)
return list(tokens)
(snip)
More information about the Python-list
mailing list