danielx wrote: > Bruno Desthuilliers wrote: > >>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 = '' >>> > > > 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. > > >>First point: the nested function only have access to names that exists >>in the enclosing namespace at the time it's defined.
oops - Sorry, said an obvious stupidity here (was very tired, should not have answered at all...) > > 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. of course. > >>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 = "". That's a side-effect of rebinding tok - it makes the name local. Even if the rebiding is done *after* first use of the name... > >>Third point : functions modifying their environment this way are usually >>considered bad form. > > > Again, this is coming from lisp, but I don't see anything wrong with > that :P. > *** > > 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... You did not rebind 'outerLocal' in your above code. > One thing I can understand is why the line tok = "" in addTok won't > work. This is because when Python sees that line, it should create a > new local variable in the scope of addTok. Yes. But this local name is referenced before assignment. > Once addTok returns, that > variable is lost. That's pretty deep, now that I've thought about it... > (snip) Sorry once again for the obvious stupidity I wrote as first point. Next time I'll go to bed instead, I promise :( -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list