Hacker News new | ask | show | jobs
by Jach 5411 days ago
The writing to variables in outer scopes is what I meant by a lack of actual name-binding, due to the way Python does assignments; it seems I expressed that poorly. Here's a better attempt. The top poster's example simply doesn't work in Python:

    >>> i = 0
    >>> def inc():
    ...   i += 1
    ...
    >>> print i
    0
    >>> inc()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in inc
    UnboundLocalError: local variable 'i' referenced before assignment
So variables are name-bound in the sense that you can read from their original name and reference but you can't assign in normal ways. (Python has closures, which I said, just not typical closures that other languages might have.) Leading to the pattern of wrapping an array or dict or class around the thing you're interested in.

    >>> i_wrapped = [0]
    >>> def inc():
    ...   i_wrapped[0] += 1
    ... 
    >>> print i_wrapped[0]
    0
    >>> inc()
    >>> print i_wrapped[0]
    1
One could argue that one shouldn't really have such mutable state inside a closure of the enclosed items, which I do, but a person expecting to (set!) or the like is going to be surprised.

Edit: I guess it should be said that Python 3 has the 'nonlocal' keyword, and Python 2 has the 'global' keyword for global cases, which allows for expected behavior. So the functionality is still there, but still needs an extra statement.

    >>> i = 0
    >>> def out():
    ...   i = 0
    ...   def inc():
    ...     nonlocal i
    ...     i += 1
    ...   print(i)
    ...   inc()
    ...   print(i)
    ... 
    >>> print(i)
    0
    >>> out()
    0
    1
    >>> print(i)
    0
1 comments

Python is a bad example here, as its scoping rules are inconsistent and frequently surprising.