x = 3
y = [3]
def test1():
x += 1
print x
def test2():
y[0] = 4
y.append(5)
print y
test2()
test1()
这段代码执行结果: test2()成功打印[4, 5], test1()却报错: UnboundLocalError: local variable 'x' referenced before assignment
想不明白,为什么会这样,全局变量在函数里可以直接打印,但是如果要改变它的值,会报错,但是test2()为什么不报错?如果把y换成dict类型,就能在函数里不需要用global声明,可以直接改变y的值,但如果是str或number,就会报错,为什么?
In fact, this question can be put aside whether the object referenced by the variable is mutable or immutable. What we need to pay attention to is the positioning of the variable, the time point and scope of the definition.
Consider the following code:
This code will throw an error:
a
是 functiontest
的 param variable, 所以它屬於一個 local variable, 他的作用域是test
函數, 我們將 1 傳進去讓 a 參考, 所以print(a)
沒有什麼大問題。但是
b
從頭到尾都沒定義, 即使依據 LEGB 原則去尋找也遍尋不著, 所以 raise 了一個NameError
.To solve this problem, maybe we can define a global variable:
Great, it looks fine this time because Python found
b
, Python 之所以會使用 globalb
那是因為在 local 我們並沒有定義b
in the global scope.Then we start assigning values to variables in the function:
Result:
The two
andprint
within the function printed out 1 and 20 not surprisingly, but why did the value ofb
printed after leaving the function be 100?Because we wrote such an
print
不令人意外地印出了 1 跟 20, 但是為什麼離開 function 之後印出b
的值是 100 呢?因為我們在函數中寫了這樣一個 賦值 兼 定義
b = 20
, 所以在test
中看到的b
都是 local 的, 不是 global 的, 所以我們對b
造成的任何更動都不會影響到 globalb
assignmentdefinition
b = 20
in the function, so theb
seen intest
are all It is local, not global, so any changes we make tob
will not affect globalb
.When local variable is not defined, Python will automatically use global variable, but not vice versa
global
Then how can we operate global variables within the function? This requires the assistance of
global
關鍵字 對b
做了說明, Python 會將test
中的b
當作是要存取 global 的變量b
而b = 20
this keyword:With the
keyword describingb
, Python will treatb
intest
as a variable to access globalb andb = 20
will only be treated as an assignment action and will not define a new local variable.UnboundLocalError
, 為什麼會這樣呢? 原因很簡單,b
在這個函數內出現了賦值兼定義的動作:b = 20
, 所以test
內的b
都是 local 的(在這裡並沒有使用 global 來指明b
是 global 的), 所以當print(b)
的時候, Python 會試圖去抓 localb
而不是 globalb
, 但是悲劇的是, 在這一步, localb
還沒被賦值, 所以才會說local variable 'b' referenced before assignment
Result:appears here
is referenced before being assigned, so naturally it won’t work. 🎜 🎜Look back at the example you gave:🎜Here, when
test1
中有x
的定義發生 (沒有 global, 且x
出現在等號左邊), 自然在參考x
, you will want to use local, but because:So when I want to get the value of the
x
reference on the right side of the equal sign, I find that it has not been assigned a value yet! Then this is the same as the above example:As for your
test2
no problem:Because y does not appear on the left side of the equal sign in
test2
中出現在等號左邊, 所以 Python 自動認定使用 global 的y
, so Python automatically assumes that globaly
is used, so naturally there is no problem!Conclusion
Observe whether local vairable is defined in a function and see if the variable name appears on the left side of the equal sign, and the variable name is not specified by
global
If a local variable is defined, Python will not look for the global variable, otherwise Python will automatically use the global vairable
If local vairable is defined but you read the reference before the variable is assigned, an UnboundLocalError will appear
To solve this problem, please remember to add
global
to specify the entire domain, otherwise this writing method should not appear (in-place operation, or assignment later)Similar problems will also occur in local function. The solution is to add
nonlocal
(Python3), but that is another story.Questions I answered: Python-QA
Python's variable scope is stipulated in this way. In test1, it can
print x
but cannot modify xSome people say "global variables in local scope should be read-only", but this condition is not met for reference variables. . .
This place of python is really confusing
Simply put, the binding of global variables cannot be changed in the local scope, and the address of the variable cannot be changed in
CPython
.See: Common Mistake 4 in: The Ten Most Common Mistakes Python Programmers Make: Misunderstanding Variable Name Parsing in Python
Not found in your
test1
函数有赋值操作x += 1
, 被Python解释器认为是函数本地作用域的变量, 但是该变量x
在赋值之前并没有被定义, 而且x
是number
, 属于不可变类型, 针对不可变类型的赋新值, 需要重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象, 但是这个新创建的对象在LEGB
, so an error will be reportedtest2
函数中,y
是个list
, It is a variable type. After append, the list still points to the same memory address. Because the list is a variable type, it can be modified in place, so no error will be reportedPython
中所有赋值操作基本都分为下面三个步骤(以a = 3
for example):Create an object to represent the value
3
Create a variable
a
, if it hasn’t been created yetConnect the variable
a
与新的对象3
to the new objecttest2
函数在执行过程中变量y
Let’s observe youry
其实是在原地修改的, 所以不需要重复创建变量; 而对于x
不可变类型来说, 要给他赋值, 就必须先创建一个新的对象, 即使名字一样, 可以看到其实如果每次不同的赋值, 实际上x
的内存地址并不相同, 这也就可以解释str
或number
You can seethat all errors will be reported🎜