When lexical scoping attacks

Consider the following Python code:

bar = []
def test():
    new = ['this', 'comes', 'from', 'test']
    bar.extend(new)
    print bar

print bar
test()
print bar

This code generates this output:

[]
['this', 'comes', 'from', 'test']
['this', 'comes', 'from', 'test']

Which is to say, bar is empty before test(), has the contents of new inside of test(), and continues to have that value when test() returns.

Now, look at this code:

bar = []
def test():
    new = ['this', 'comes', 'from', 'test']
    bar = new
    print bar

print bar
test()
print bar

Which outputs:

[]
['this', 'comes', 'from', 'test']
[]

The value of bar is only changed inside test(). Upon further reflection, I realized that the assignment was assigning a new local variable inside the test() scope, whereas accessing bar returns the variable from the outer scope, which is then modified.

This behavior doesn’t make a whole lot of sense to me.

2009/06/30
Previously On Atomized:

Discussion

To get what you expect you’d need to put “global bar” at the top of test.

Brett
2009/06/30

I think the that it would make most sense if “bar.extend(new)” threw an error without the “global bar”

Ian Lewis
2009/07/23

Participate