setting variables in outer functions

Neil Cerutti horpner at yahoo.com
Tue Oct 30 11:25:54 EDT 2007


On 2007-10-29, Steven Bethard <steven.bethard at gmail.com> wrote:
> Hrvoje Niksic wrote:
>> Tommy Nordgren <tommy.nordgren at comhem.se> writes:
>> 
>>> Given the following:
>>> def outer(arg)
>>>      avar = ''
>>>      def inner1(arg2)
>>>           # How can I set 'avar' here ?
>> 
>> I don't think you can, until Python 3:
>> http://www.python.org/dev/peps/pep-3104/
>
> But it definitely does work in Python 3 if you use 'nonlocal'::
>
>      Python 3.0a1+ (py3k:58681, Oct 26 2007, 19:44:30) [MSC v.1310 32 bit
>      (Intel)] on win32
>      Type "help", "copyright", "credits" or "license" for more
>      information.
>      >>> def f():
>      ...     x = 1
>      ...     def g():
>      ...         nonlocal x
>      ...         x = 2
>      ...     print(x)
>      ...     g()
>      ...     print(x)
>      ...
>      >>> f()
>      1
>      2
>
> That said, I'd like to see the reason you think you want to do
> this.

It's allows a standard programming idiom which provides a
primitive form of object oriented programming using closures to
represent state.

def account(opening_balance):
  balance = opening_balance
  def get_balance():
    nonlocal balance
    return balance
  def post_transaction(x):
    nonlocal balance
    balance += x
  return balance, post_transaction

fred_balance, fred_post = account(1500)
joe_balance, joe_post = account(12)
fred_post(20)
joe_post(-10)
fred_balance()
1520
joe_balance()
2

Python classes will of course nearly always win, though the idiom
looks like it might be faster (I don't have Python 3000 to try it
out).

-- 
Neil Cerutti
It isn't pollution that is hurting the environment; it's the impurities in our
air and water that are doing it. --Dan Quayle



More information about the Python-list mailing list