python函數錯誤分析

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

持續更新....


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章