4.2. Naming and binding
4.2.1. Binding of names
If a name is bound in a block, it is alocal
variable of that block, unless declared as nonlocal
or global
.
If a name is bound at the module level, it is a global variable.
(The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free
variable.
4.2.2. Resolution of names
When a name is not found at all, a NameError
exception
is raised. If the current scope is a function scope, and the name refers to a local variable that has not yet been bound to a value at the point where the name is used, an UnboundLocalError
exception
is raised. UnboundLocalError
is
a subclassof NameError
.
If a name binding operation occursanywherewithin
a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when
a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of
the block for name binding operations.
num1 = [3] #全局變量
num2 = [333] #全局變量
def test1():
print(num1) #UnboundLocalError: local variable 'num' referenced before assignment
num1 = num2
print(num2)
test1()
未看API中上述內容分時自己的分析
看API中以下分類
1.The Python Language Reference
8.6. Function definitions
2.The Python Tutorial
4.6. Defining Functions
然後是根據上述信息自己的分析:
分析:
1.一個函數定義是一個可執行語句 --- 即邏輯語句 --- 在被評估時是按邏輯語句整體評估的
2.所有在函數中變量的賦值都會把值存儲在本地符號表中,即當評估師num1 = num2時會把num1當做本地變量,這句話沒毛病
3.但是此時再看print(num1),解釋器會發現...搞毛啊...這局部變量都還沒有賦值就是用了? ---- 即變量未初始化/未定義
4.賦值語句作用: 綁定名稱和值 和 修改可變對象的屬性或項目值 --- 因而這裏報本地未綁定錯誤
這裏的錯誤實際上和變量爲定義異常一樣,類似於
def test(): #定義函數
print(a) #NameError: name 'a' is not defined
a = 3
test() #調用函數
但是因爲下面有一句num1 = num2,所以不再是單純的變量未定義異常,而是變量在賦值之前被引用,即未綁定異常,因爲在函數內部,因而是本地未綁定錯誤
#可以看到下面的函數執行不會報錯
>>> num3 = [1, 2, 3]
>>> num4 = [3, 2, 1]
>>> def test2():
... num3 = num4
#1.命名和綁定中的解釋: 在代碼塊中爲名稱指定綁定,該名稱是局部變量
#2.函數定義中的解釋: 所有在函數內部的賦值都會把值存儲在該函數的本地符號表中
... print(num3)
... print(num4)
...
>>> test2()
[3, 2, 1]
[3, 2, 1]
#驗證函數內部的num3是局部變量
>>> num3
[1, 2, 3]
>>> num4
[3, 2, 1]
>>>
感覺熟悉API很有必要.....
2017年4月16日16:05:11
持續更新....