2014-02-24 140 views
0

我想了解Python範圍。看到這個例子:Python本地範圍混亂

x = 'foo' 

def outer(p): 
    print x 
    x = 'bar' 
    def inner(p): 
     print x 
    inner(1) 

print x 
outer(1) 

該代碼產生以下錯誤:

Traceback (most recent call last): 
    File "scopes2.py", line 11, in <module> 
    outer(1) 
    File "scopes2.py", line 4, in outer 
    print x 
UnboundLocalError: local variable 'x' referenced before assignment 

現在,如果我刪除x = 'bar'線,然後將其運行正常。

爲什麼我不能使用全球xprint xouter()直到我重新綁定到'bar'

回答

3

任何時候你在一個函數中都有一個賦值,該變量對整個函數來說都是本地的。你不能只是引用全局「直到局部分配」


What are the rules for local and global variables in Python(重點煤礦)

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a new value anywhere within the function’s body, it’s assumed to be a local. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as ‘global’.

Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.

+0

這是否意味着解釋器不會在執行過程中逐行處理代碼呢?我試圖在'outer()'函數中加入if 1:pass'' else:x ='bar'\ ndo_error'。雖然執行永遠不會到達else分支,但它仍然抱怨未定義的局部變量。另一方面,它完全沒有抱怨未定義的'do_error',並且如果我刪除了該作業,則完美運行。 – Mkoch

+1

是的,解釋器評估整個函數來確定全局和本地 – mhlester

+0

如果'locals()'也不包含在'x ='bar''行之前的名字'x',是否有方法來「查找」它在那個時候?我的意思是要找到這樣一個名字可能在這個區塊中被綁定? – Mkoch

1

要參考全球x從功能,使用

def outer(p): 
    global x 
    print x 
    x = 'bar' 
    ... 

注意,分配給x將重新綁定全球x了。如果你不想發生,重命名其中一個變量(或者更好的是,不要使用全局變量)。

+0

全球需要的,如果我想改變全局X,而不是在我的地方重新綁定它的範圍,但這並不回答我的問題imho – Mkoch