开发者

Python scope problems only when _assigning_ to a variable

So I'm having a very strange error right now. I found where it happens, and here's the simplest code that can reproduce it.

def cause_an_error():
    some_var = False
    def some_nested_func():
        print some_var
        #some_var = True
    some_nested_func()

>>> cause_an_error()
False

If you run it as-is, it prints "False". But if you uncomment that line, it gives an error:

    Traceback (most recent call last):
  File "<pyshell#224>", line 1, in <module>
    cause_an_error()
  File "<pyshell#223>", line 6, in cause_an_error
    some_nested_func()
  File "<p开发者_如何学运维yshell#223>", line 4, in some_nested_func
    print some_var
UnboundLocalError: local variable 'some_var' referenced before assignment

Notice the error occurs on the line that worked just fine before.

Any ideas what causes this and how I can fix this? I'm using Python 2.6.1.


The inner function, some_nest_func, has its own scope, and the fact that you are assigning to some_var somewhere within that scope makes some_var local to that scope. This has the effect of hiding the some_var assigned in the outer function. They are two different variables.

The upshot of all this is that you are printing some_nest_func's version of some_var before you assign to it.

If you need to manipulate some variable both in and outside the inner function, there isn't a clean way to it, AFAIK. A simple work-around is to replace the variable with a single-element array and manipulate that isn't (don't assign to the array variable, of course).


This can't be fixed in 2.x without refactoring the code. 3.x adds nonlocal to solve this.


You can do this by changing a value of a referenced (read mutable) variable such as dict, although ugly, this solution (transcribed from an answer to a similar question) should work:

def avoid_an_error():
    D = {"some_var": False}
    def some_nested_func():
        D["some_var"] = True
        print D["some_var"]
    some_nested_func()

>>> avoid_an_error()
True
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜