Python变量作用域¶
所谓作用域(Scope), 就是变量的作用范围, 就是变量可以在哪个范围内使用. 有些变量可以在整段代码的任意位置使用, 有些变量只能在函数内部使用, 有些变量只能在for循环内部使用.
变量的作用域由变量的定义位置决定, 在不同位置定义的变量, 它的作用域是不一样的.
局部变量¶
在函数内部定义的变量, 它的作用域也仅限于函数内部, 这样的变量称为局部变量(Local Variable).
当函数被执行时, Python会为其分配一块临时的存储空间, 所有在函数内部定义的变量, 都会存储在这块空间中. 而在函数执行完毕后, 这块临时存储空间随即会被释放并回收, 该空间中存储的变量自然也就无法再被使用了.
值得一提的是, 函数的参数也属于局部变量, 只能在函数内部使用.
全局变量¶
除了在函数内部定义变量, Python还允许在所有函数的外部定义变量, 这样的变量称为全局变量(Global Variable).
和局部变量不同, 全局变量的默认作用域是整个程序, 即全局变量既可以在各个函数的外部使用, 也可以在各个函数的内部使用.
定义全局变量的方式有以下两种:
- 在函数体的外部定义的变量, 一定是全局变量;
Example:
# 定义全局变量
msg = 'hello, world'
def showMsg():
# 在函数内部使用全局变量
print('在函数体内, msg = ', msg)
showMsg()
# 在函数外部使用全局变量
print('在函数体外, msg = ', msg)
- 在函数体内定义全局变量, 即使用
global关键字对变量进行修饰后, 该变量就会称为全局变量.
Example:
def showMsg():
# 在函数内部定义全局变量
global msg
msg = 'hello, world'
# 在函数内部使用全局变量
print('在函数内部, msg = ', msg)
showMsg()
# 在函数外部使用全局变量
print('在函数外部, msg = ', msg)
注意
在使用global关键字修饰变量名时, 不能直接给变量赋值, 否则会引发语法错误.
要先声明, 再赋值.
全局变量和局部变量的同名问题¶
全局变量可以在程序中任何位置被访问甚至修改, 但是, 当函数中定义了和全局变量变量同名的局部变量时, 那么在当前函数中, 无论是访问还是修改该同名变量, 操作的都是局部变量, 而不是全局变量.
注解
当函数内部的局部变量和函数外部的全局变量同名时, 在函数内部, 局部变量会”遮蔽”同名的全局变量.
Example:
# 定义全局变量
msg = 'hello, world'
def showMsg():
print(msg)
# 定义同名的局部变量
msg = 'ABC'
showMsg()
执行上面的程序, 运行报错:
UnboundLocalError: local variable 'msg' referenced before assignment
意思是: 所访问的变量msg还未定义, 这是什么原因呢?
Python语法规定, 在函数内部对不存在的变量赋值时, 默认就是定义新的局部变量.
在上面的程序中, 在函数的内部定义了一个新的msg局部变量, 由于该局部变量和全局变量msg同名,
所以局部变量就是”遮蔽”全局msg变量, 再加上局部变量msg在print(msg)之后才被初始化,
违反了”先定义后使用”的原则, 因此程序会报错.
注解
Python程序在运行时, 先导入整个程序, 再执行. 很多初始化工作在导入时就完成了(比如上面的示例程序中, 局部变量”遮蔽”全局变量的工作).
那么, 如果就是想在函数中访问甚至修改被”遮蔽”的变量, 怎么办呢? 可以采取以下两种方法:
- 如果希望程序依然能够访问
msg全局变量, 且在函数中重新定义msg局部变量, 也就是在函数中可以访问被遮蔽的全局变量, 此时可以通过globals()函数来实现.
Example:
msg = 'global'
def showMsg():
# 通过globals()函数访问甚至修改全局变量
print(globals()['msg'])
globals()['msg'] = 'Hello, world'
# 定义局部变量
msg = 'local'
showMsg()
print(msg)
运行结果为:
global
Hello, world
- 在函数中用
global语句声明全局变量, 这样在函数中对该变量的操作都是对全局变量的操作, 赋值不会定义全局变量.
Example:
msg = 'global'
def showMsg():
global msg
# 访问全局变量
print(msg)
# 修改全局变量的值
msg = 'Hello, world'
showMsg()
print(msg)
获取指定作用域范围中的变量¶
在一些特殊场景中, 我们可能需要获取某个作用域内所有的变量, Python提供了以下三种方式:
globals()函数
globals()函数为Python的内置函数, 它可以返回一个包含全局范围内所有变量的字典, 该字典中的每个键值对, 键为变量名, 值为该变量的值.
注意
globals()函数返回的字典中, 会默认包含有很多变量, 这些都是Python主程序设置的.
我们甚至可以通过globals()函数, 以键值对的形式访问变量, 如果需要, 还可以修改它的值.
Exmaple:
msg = 'hello, world'
print(globals())
# 通过globals()函数, 以键值对的形式访问变量
print('msg = ', globals()['msg'])
# 通过globals()函数, 以键值对的形式修改变量的值
globals()['msg'] = 'ABC'
print(msg)
locals()函数
locals()函数也是Python内置函数之一, 通过调用该函数, 可以得到一个包含当前作用域内所有变量的字典.
这里所谓的”当前作用域”, 指的是在函数内部调用locals()函数, 会获得包含所有局部变量的字典;
而在全局作用域中调用locals()函数, 其功能和globals()函数相同.
vars(object)
vars()函数也是Python内置函数, 其功能是返回一个指定object对象范围内所有变量组成的字典.
如果不传入object参数, vars()和locals()的作用完全相同.