Nested function scope problem
Simon Forman
rogue_pedro at yahoo.com
Fri Jul 21 22:36:37 EDT 2006
Gerhard Fiedler wrote:
> On 2006-07-21 21:05:22, Josiah Manson wrote:
>
> > 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.
>
> I'm no Python specialist, so here's just some guesses... I don't know how
> to make variables known inside the inner function. It seems just using the
> names there overrides the outside names. It also seems that local variables
> are in some kind of dictionary; so maybe you can access them through that
> somehow.
>
> One other solution (a bit ugly) would be to make this a class with two
> static methods (breakLine and _addTok) and two static attributes (_ls and
> _tok).
>
> Still another (also ugly) would be to pass both tok and ls to addTok() and
> pass tok back out again. (I think ls doesn't have to be passed back,
> because it is a list and so its data gets modified. tok's data doesn't get
> modified, so local changes don't propagate to the outside.)
>
> Gerhard
That third option seems to work fine.
def breakLine(s):
"""Break a string into a list of words and symbols.
"""
def addTok(tok, ls):
if len(tok) > 0:
ls.append(tok)
tok = ''
return tok
ls = []
tok = ''
splitters = '?()&|:~,'
whitespace = ' \t\n\r'
for c in s:
if c in splitters:
tok = addTok(tok, ls)
ls.append(c)
elif c in whitespace:
tok = addTok(tok, ls)
else:
tok = tok + c
tok = addTok(tok, ls)
return ls
#some tests to make sure it works
print breakLine('carolina(Prada):cat(X,Y)')
print breakLine('trouble :bird (X ) &cat ( Y )')
print breakLine('?trouble')
# Prints:
['carolina', '(', 'Prada', ')', ':', 'cat', '(', 'X', ',', 'Y', ')']
['trouble', ':', 'bird', '(', 'X', ')', '&', 'cat', '(', 'Y', ')']
['?', 'trouble']
More information about the Python-list
mailing list