基础篇_010_函数_全局变量与局部变量
----定义
1. 全局变量: 一经定义就能在整个.py文件中使用(表现为没有缩进),我们在最初定义变量的时候都是全局变量。
2. 局部变量: 在某一个代码块中定义(表现为有缩进),只要一出这个代码块就会失效。
大家可以这样来想 ===》我们的理想是"共产主义社会",在这样的社会中,一切生产资料共享,这就相当于是"全局变量";然而总有一些而会有点儿私心,认为有些东西就应该只有自己享有,别人不能(eg: 自己的女朋友),这就相当于局部变量。
----使用
1. 当一个模块(eg: 函数...)中定义的局部变量与全局变量重复的时候,局部变量便会覆盖全局变量(这里的覆盖并不是值覆盖,只是索引覆盖 ===》全局变量的值不变,而且已然存在,只不过在模块中不能通过变量名的方式直接访问了)。
2. 当(1)中的情况出现时,记住一点:二者毫不相干 ===》修改局部变量不会影响全局变量。
3. 若是想在函数中重新定义全局变量,那么可以在变量名前加上"global"(相当于获取到C语言中的指针,C++、Java中的引用)。
name = "simba"
def change_name():
global name
name = "wang"
print(name) # 输出经过global修饰的局部变量(其实是全局变量的引用)
change_name() # 输出:wang
print(name) # 输出全局变量:wang
4. 需要注意的是: 虽然在函数中,不使用"global"关键字,就不能对全局变量重新赋值(因为此时的赋值操作python会理解为重新创建一个变量),但是没说不可以修改全局变量(如果说全局变量是可变类型:列表、字典),当然,clear()也能用 ===》
name = ["simba", "wang"] # 声明一个全局变量
def add_name():
# 不使用"global"关键字
name.append("vivian") # 对全局变量进行修改
add_name()
print(name) # 输出:['simba', 'wang', 'vivian']
5. 使用"global"关键字的时候需要注意: 尽量将全局声明放在开头,否则python将会产生"二义性"(不知道是函数中一开始声明的局部变量,还是后来通过全局声明"借来"的变量) ===》
name = "sss"
def add_name():
name = "ddd"
global name
add_name() # name 'name' is assigned to before global declaration
# 报错:名叫'name'的变量在全局声明之前就已经被分配了
6. 很绕是吧,没关系,这种情况前辈们已经都考虑过了,所以在python行业中有这样一条规定:全局变量的名字全部大写、局部变量的名字全部小写。
----nonlocal
上面说了"global"关键字,它的作用是在函数中获取全局变量的引用(或者叫指针),从而让用户能够在函数中重新定义全局变量,那来看一下这一段代码(所有的def都可以跳过,当函数被调用的时候再来看) ===》
1 name = "simba" # step 1 step 7 的时候更改为"vivian"
2 def weihou():
3 name= "wang" # step 4
4 # step 7 更改全局变量的时候保持不变("wang"与全局变量没关系)
5 def weiwiehou():
6 global name # step 6 借一个"name"
7 name = "vivian" # step 7 重新定义全局变量
8 weiwiehou() # step 5
9 print(name) # step 8
10 # 由于在weiwiehou()中更改的是全局变量,所以这里还是输出:wang
11 print(name) # step 2 # 输出:simba
12 weihou() # step 3 # 输出:wang
13 print(name) # step 9 # 输出:vivian
可以实现修改上一层函数的局部变量,但不修改全局变量嘛?这并不是白日梦,python为我们提供了一个特殊的关键字——"nonlocal"。
1 name = "simba" # step 1
2 def weihou():
3 name= "wang" # step 4 # step 7 的时候更改为"vivian"
4 def weiwiehou():
5 nonlocal name # step 6 借一个上一级的"name"
6 name = "vivian" # step 7 重新定义上一级变量
7 weiwiehou() # step 5
8 print(name) # step 8
9 # 由于在weiwiehou()中更改的是上一级变量,所以这里是输出:vivian
10 print(name) # step 2 # 输出:simba
11 weihou() # step 3 # 输出:vivian
12 print(name) # step 9 # 由于没有更改全局变量,所以这里输出:simba
有了"global"和"nonlocal"这两个关键字后,全局变量和局部变量的关系也逐渐紧密。