At http://tour.golang.org/#39, I found the following sample code:
1 | package main |
Its document reads:
… functions are full closures. The adder function returns a closure. Each closure is bound to its own sum variable.
Take that into consideration, it might be easier to understand the execution result:
1 | 0 0 |
To me, variable sum
is similiar to ‘instance variable’, in Object-oriented’s terminology. However, in Python, things can be quite different.
1 | def adder(): |
The code looks roughly the same, but it will raise the following exception:
1 | Traceback (most recent call last): |
This is because if sum
is to be modified, Python must decide which variable to change. **sum += x**
is the same as **sum = sum + x**
, and **sum = **
suggests it’s a local variable, since all variable is by default local in Python. Given that, expression **sum + x**
can not be evaluated because sum
, as a local variable, is still undefined here.
If the **sum += x**
line is removed, and **sum + x**
is returned directly, the result will be:
1 | 0 0 |
It runs okay, but the result is wrong. Where does function f get the value of sum
? If Python cannot find a variable in locals(), it will try to find it from the scope above it, i.e. function adder
, and sum
is indeed defined in it. The real Python equivelent of the Go program above will be:
1 | class adder: |
Functions are already first class objects in Python. Here we create a class that its instance behaves like a function, so it is a function because of duck typing.
P.S. A reader is so kind to point out that I can use the `nonlocal’ keyword in python3. http://www.python.org/dev/peps/pep-3104/