Python——函数入门(三)
程序员文章站
2022-04-15 15:13:23
一、变量作用域 当程序定义一个变量时,这个变量是有它的作用范围的,变量的作用范围称为变量的作用域。根据变量的位置,分为两种: 局部变量:局部变量就是在函数中定义的变量,包括参数,都是局部变量,局部离开函数后,将不能被访问。 全局变量:不在函数内定义、全局范围内定义的变量,都是全局变量,全局变量可以在 ......
一、变量作用域
当程序定义一个变量时,这个变量是有它的作用范围的,变量的作用范围称为变量的作用域。根据变量的位置,分为两种:
- 局部变量:局部变量就是在函数中定义的变量,包括参数,都是局部变量,局部离开函数后,将不能被访问。
- 全局变量:不在函数内定义、全局范围内定义的变量,都是全局变量,全局变量可以在所有函数中被访问。
在python中,提供了三个工具函数获取指定范围内变量和值组成的字典。
- globals():返回当前作用域全局变量的字典;无论在哪里使用,都会获取全局变量。
- locals():返回包含当前范围的局部变量的字典;当在全局范围内使用,会获取全局范围内所有变量组成的字典。
- vars():当没有参数时,相当于locals();有一个参数时,相当于object.__dict__。
使用globals()和locals()获取全局变量时,不应该被修改,修改会改变全局变量本身。而locals()获取局部变量时,即使修改了,也不会对局部变量产生影响。
globals(),例:
a = 1
def test():
b = 2
print (globals())
test()
# 打印全局变量 {'__name__': '__main__', '__doc__': none, '__package__': none, '__loader__': <class '_frozen_importlib.builtinimporter'>, '__spec__': none, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': 1, 'test': <function test at 0x0000000002eac1e0>}
globals()
# 打印全局变量 {'__name__': '__main__', '__doc__': none, '__package__': none, '__loader__': <class '_frozen_importlib.builtinimporter'>, '__spec__': none, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': 1, 'test': <function test at 0x0000000002eac1e0>}
locals(),例:
a = 1
def test():
b = 2
print (locals())
test()
# 打印局部变量 {'b': 2}
print (locals())
# 打印全局变量 {'__name__': '__main__', '__doc__': none, '__package__': none, '__loader__': <class '_frozen_importlib.builtinimporter'>, '__spec__': none, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': 1, 'test': <function test at 0x0000000002eac1e0>}
vars(),例:
class test01:
k1 = 1
def test02():
k2 = 2
print (vars())
k3 = 3
test01.test02()
# 打印test02()的局部变量 {'k2': 2}
print (vars())
# 打印全局变量 {'__name__': '__main__', '__doc__': none, '__package__': none, '__loader__': <class '_frozen_importlib.builtinimporter'>, '__spec__': none, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'test01': <class '__main__.test01'>, 'k3': 3}
print (vars(test01))
# 打印类的属性 {'__module__': '__main__', 'k1': 1, 'test02': <function test01.test02 at 0x00000000023892f0>, '__dict__': <attribute '__dict__' of 'test01' objects>, '__weakref__': <attribute '__weakref__' of 'test01' objects>, '__doc__': none}
print (test01.__dict__)
# 打印类的属性 {'__module__': '__main__', 'k1': 1, 'test02': <function test01.test02 at 0x00000000023892f0>, '__dict__': <attribute '__dict__' of 'test01' objects>, '__weakref__': <attribute '__weakref__' of 'test01' objects>, '__doc__': none}
全局变量虽然可以被所有函数访问,但是如果在函数内定义了与全局变量同名的变量,就会发生局部变量遮蔽全局变量的情况,例:
a = 1
def test():
print (a)
test()
# 运行成功,打印 1
def test02():
a = 2
print (a)
test02()
# 函数内部对不存在的变量赋值,会重新定义新的局部变量,打印 2
def test03():
print (a)
a = 3
test03()
# 报错unboundlocalerror: local variable 'a' referenced before assignment,由于a=3这段代码重新定义了局部变量,所以a全局变量被被遮蔽。
二、使用global语句在函数中声明全局变量
为了避免在函数中对全局变量赋值,可以通过global语句声明全局变量。
例:
a = 1
def test():
# 声明a是全局变量,后面的语句将不会重新定义局部变量
global a
print (a) # 打印 1
# 对全局变量进行赋值
a = 2
test()
# 打印 1
print (a)
# 打印 2
三、局部函数
前面我们看到的都是全局函数,我们还可以在函数体内定义函数,这称为局部函数,局部函数在默认情况下,对外部是隐藏的,只能在其封闭函数内有效,如果想在其他作用域中使用局部函数,其封闭函数可以返回局部函数。
例:
# test()函数根据不同的参数,选择调用不同的局部函数
def test(x):
def a(x):
return x * x
def b(x):
return x
if x != 0:
return a(x)
else:
return b(x)
print (test(2))
# 打印 4
print (test(0))
# 打印 0
局部函数的变量也会遮蔽他所在函数的局部变量,例:
def test01():
a = 1234
def test02():
print (a)
a = 4321
test02()
test01()
# 报错 unboundlocalerror: local variable 'a' referenced before assignment
上面的代码中,由于在test02()函数中重新定义了新的局部变量a,test02()函数中定义的局部变量a遮蔽了他所在函数test01()中的局部变量a,我们可以通过nonlocal语句声明访问赋值语句只是访问该函数所在函数的局部变量。
注意,nonlocal语句只能在嵌套函数中使用,并且在外层函数中必须定义了相关的局部变量,否则会报错。
例:
def test01():
a = 1234
def test02():
nonlocal a # 声明a是test01()的局部变量
print ('01',a)
a = 4321 # 改变外层函数局部变量的值
print ('02',a)
print ('03',a)
test02()
print ('04',a)
test01()
# 打印
# 03 1234
# 01 1234
# 02 4321
# 04 4321
上一篇: Python笔记:模板方法模式
下一篇: js utc转当地时间