全局变量和局部变量
命名空间
1. 函数外部
函数外部声明的变量,可以被所有函数公共访问【所有地方都能访问这个变量】
函数的外边是一个空间:全局命名空间
2. 函数内部
一个函数中声明的变量,智能在函数内部去访问【函数的外面是访问不到这个变量】
函数的内部是一个空间,局部命名空间
作用域
作用域:就是起作用的范围
什么时候使用
全局变量
一旦一个数据,要被多个函数同时访问是,就可以将这个变量声明为全局变量。
全局变量声明在全局命名空间中,作用域是当前文件中的所有位置。
局部变量
局部变量:声明在函数内部的变量,只能在当前函数内部访问,函数执行完成(堆内存执行完成后函数就回收)
后局部变量就随着函数被回收了!
一旦当一个数据,在函数中临时使用,使用完之后就没有作用的数据,就可以声明为局部变量在当前函数内部使用。
操作方式
全局变量的访问
-
函数内部:
- 可以直接访问全局变量中的数据
-
函数外部:
- 可以直接访问全局变量中的数据
全局变量的修改
-
不可变类型全局变量:如 字符串
如果要修改的全局变量是不可变类型,直接使用global 引入并修改
name = "tom" def test(): global name name = "jerry" test() print(name) # jerry
-
可变类型全局变量:如 列表
修改可变类型内部的数据,直接修改即可。
给可变类型全局变量重新赋值,需要使用 global关键字 引入
lst = [1] def test(): # 修改可变类型内部的数据,直接修改即可 lst.append(2) test() print(lst) # [1, 2] ======================= lst = [1] def test(): # 给可变类型全局变量重新赋值,需要使用 global关键字引入 global lst lst = [1,2,3] test() print(lst) # [1, 2, 3]
使用函数查询全局变量和局部变量
如果一个 python文件中会出现全局变量和局部变量,能否通过固定的语法查询到这些出现的变量,
让我们可以直观的看到一个文件中都有哪些全局变量,一个函数中都有哪些局部变量?
- globals() 访问一个文件中的全局变量
- locals() 访问代码所在位置命名空间中的变量
- 放在函数中,访问的就是当前函数的局部变量
- 放在函数外,访问的就是和 globals() 一样的全局变量
name = "tom"
age = 18
def test():
name = "jerry"
lst = [18]
print(locals())
#
test()
print(globals())
print(locals())
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000028A9D6AEFD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'c:/Users/Administrator/Desktop/cs.py', '__cached__': None, 'name': 'tom', 'age': 18, 'test': <function test at 0x0000028A9D5C51F0>}
变量的查询顺序
# 思考,下面的代码运行出现什么结果?为什么?
name = "tom"
def test():
print(name)
name = "jerry"
test()
- 表现:会出现 UnboundLocalError 错误,使用了一个未赋值的局部变量
- 规则:变量使用时,查询顺序就近原则【找变量离自己声明最近的一份命名空间】
python 中有一个固定的查询顺序,LEGB原则【就近原则】:
- L -> Local 本地:局部 函数内部声明的变量
- E -> Enclosing:嵌套:函数内部
- G -> Global:全局:python文件的内部
- B -> Builtins:python内建
- 底层:函数内部使用一个变量时,底层代码将变量的声明提升到函数的头部,但是赋值的过程还在原来的位置,此时如果在赋值之前使用变量,就会出现 变量和值 没有绑定的情况,于是就出现了 UnboundLocalError