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/