如果函数中存在该变量的赋值语句,则将其视为局部变量。 累积赋值语句(如 +=)也被视为赋值语句。
它不考虑何时执行赋值语句。 一旦被视为局部变量,它从头到尾都是局部变量。
一、这段代码探究的是,函数的参数传递,与作用域
a = 10
print("local_id(a):", id(a))
def test(a):
print("begin_id(a):", id(a))
a = a + 1
print('a:', a)
print("end_id(a):", id(a))
test(a)
local_id 和 begin_id 一样表明的就是 python 中的引用传递
begin_id(a) 中的 id(a) 的 a 是局部变量,
但是这个局部变量 和 全局变量 local_id(a) 中 id(a) 的 a 指向同一块内存,所以结果是一样的
二、探究上述的定理(或说成是现象)
程序一
a = 10
def test():
print(a)
print(a)
test()
程序二
a = 10
def test():
print(id(a))
a = a + 1
print(a)
test()
# 报错: UnboundLocalError: local variable 'a' referenced before assignment
程序三
a = 10
def test():
print(a)
if False:
a = a + 1
print(a)
test()
# 报错: UnboundLocalError: local variable 'a' referenced before assignment
程序四
a = 10
def test():
if False:
a = a + 1
print(a)
test()
# 报错: UnboundLocalError: local variable 'a' referenced before assignment
程序五
if False:
a = a + 1
print(a)
# 报错: name 'a' is not defined
对比程序一和程序二,由于程序一中的 test 函数中存在 a 被赋值的语句,所以在这整个局部作用域内都被解释为局部变量,而第一次打印 a 时, 变量 a 还未指向内存所以打印失败
而程序二就相当容易理解了,在局部变量中没有找到 a,就去全局变量中找了
而对比于程序二和程序三,顺应上述的总结,也可以理解此时的程序三,即使 "if False: a = a + 1 " 赋值
语句一定不会被执行,但是此时变量 a,仍然要被解释为局部变量
同时,对比一下此时的程序三和程序四,可以知道: a 变量确实由于 "if False: a = a + 1 " 赋值语句被识别并创建为局部变量,但并未指向有效的内存空间
最后来看程序五,可以知道全局程序的情况下, "if False: a = a + 1 "这种赋值语句并不会被识别,并优先创建出变量(导致报错是"变量a未被定义),而是边执行语句边创建变量。而函数中是直接先创建需要的局部变量,然后再去根据具体的赋值情况,指向内存的空间