accumulator generators

Hans Nowak zephyrfalcon!NO_SPAM! at gmail.com
Fri May 30 18:58:09 EDT 2008


Cameron wrote:
> On May 30, 1:04 pm, "Diez B. Roggisch" <de... at nospam.web.de> wrote:
>> Cameron schrieb:
>>
>>
>>
>>> I was reading this <a href="thishttp://www.paulgraham.com/icad.html">Paul
>>> Graham article</a> and he builds an accumuator generator function in
>>> the appendix. His looks like this:
>>> <pre>
>>> def foo(n):
>>>   s = [n]
>>>   def bar(i):
>>>     s[0] += i
>>>     return s[0]
>>>   return bar
>>> </pre>
>>> Why does that work, but not this:
>>> <pre>
>>> def foo(n):
>>>   s = n
>>>   def bar(i):
>>>     s += i
>>>     return s
>>>   return bar
>>> </pre>
>> Because python's static analysis infers s as being a variable local to
>> bar in the second case - so you can't modify it in the outer scope.
>>
>> In the future, you may declare
>>
>> def bar(i):
>>      nonlocal s
>>      ...
>>
>> Diez
> 
> thanks for the response. Just to make sure I understand- Is the reason
> it works in the first case because s[0] is undefined at that point (in
> bar), and so python looks in the outer scope and finds it there?

You can refer to variables in enclosing scopes, just not redefine them in that 
same scope.  That's why in the first example, bar can refer to to s (defined in 
foo).  By assigning to s[0], it modifies the list, which is OK; trying to 
redefine the name 's' (like the second example tries to do) would not be OK.

Also see: http://zephyrfalcon.org/labs/python_pitfalls.html (pitfall #6).

-- 
Hans Nowak (zephyrfalcon at gmail dot com)
http://4.flowsnake.org/



More information about the Python-list mailing list