Python中的每一个变量都有自己的作用域,这个作用域限制了变量的作用范围,同时也节省了很多空间,再变量执行完自己作用后,自动销毁。以下主要就是介绍两种作用域:全局作用域、局部作用域,以及变量的命名空间
目录
1. 全局作用域
全局作用域:函数之外的空间,通俗来讲,只要命名在函数之外都是全局作用域,此时的变量叫做全局变量
全局作用域的周期:程序执行的时候就被创建,再程序执行结束后销毁
全局变量可以任何位置访问
y = 2 # y是全局变量
print("全局变量y = ", y)
=======================
全局变量y = 2
进程已结束,退出代码0
2. 局部作用域
也就是在函数内部的空间,在函数里面定义的变量叫做局部变量
生命周期:在函数调用时创建,在调用结束时销毁
每次调用函数的时候,都会生成一个新的作用域
重点:全局变量可以在任何位置访问,而局部变量只能在此局部作用域内访问,再函数外面是访问不到函数内的变量的
def fn():
a=10
print("内部a=",a)
print("外部a=",a) # 报错,访问不到函数内部
===========================
NameError: name 'a' is not defined
进程已结束,退出代码1
a=10
def fn():
print("内部a=",a)
print("外部a=",a) # 报错,访问不到函数内部a
fn()
========================
外部a= 10
内部a= 10
进程已结束,退出代码0
使用变量的时候,会优先在当前作用域中寻找该变量,如果有就使用,没有则继续往上一级作用域寻找,如果全局作用域都没有就会报错
def fn1():
a = 20
def fn2():
a = 10
print(a)
fn2()
fn1()
==========================
10
进程已结束,退出代码0
python中函数是可以嵌套使用的,外部函数调用内部函数,先执行fn1(),然后再执行fn2(),然后从内到外去寻找变量a,然后输出
局部变量是只能访问全局变量的,但是并不能修改全局变量的值,因为他们的作用域不同,是没有权限修改的,如果非要修改,可以在局部作用域中声明变量为全局变量即可,此时就会用到global关键字
3. global
global:将变量声明为全局变量
a = 1
def fn():
global a
a = 2
print("内部a = ",a)
print("修改前-外部a = ",a)
fn()
print("修改后-外部a = ",a)
==============================
修改前-外部a = 1
内部a = 2
修改后-外部a = 2
进程已结束,退出代码0
可以看到,当声明a为全局变量后,即可修改a的值,此后a在全局作用域中的值也会跟着发生改变
4. nonlocal
再局部内嵌函数中使用,用来在函数或其他作用域中使用外层(非全局)变量
def f1():
a = 1
def f2():
a = 2
print("内部a=",a)
f2()
print("外部a=",a)
f1()
====================
内部a= 2
外部a= 1
进程已结束,退出代码0
此时的f2中的a的作用域属于f2中
def f1():
a = 1
def f2():
nonlocal a
a = 2
print("内部a=",a)
f2()
print("外部a=",a)
f1()
============================
内部a= 2
外部a= 2
进程已结束,退出代码0
使用nonlocal之后,f2中的a就属于f1的作用域了,所以在f2中修改值,f1的值也会发生改变
5. 命名空间
指的是变量存储的位置,每一个变量都需要存储到指定的命名空间中
locals():获取当前作用域的命名空间,返回一个字典
a = 'hello'
print(locals())
def fn():
b = 'world'
print(locals())
fn()
==============================
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002437D7B1940>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\lenovo\\PycharmProjects\\博客\\10.作用域与命名空间\\作用域.py', '__cached__': None, 'a': 'hello'}
{'b': 'world'}
进程已结束,退出代码0
当使用global之后,b的作用域就变成了全局作用域
a = 'hello'
def fn():
global b
b = 'world'
print(locals())
fn()
print(locals())
==========================
{}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002282E3F1940>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\lenovo\\PycharmProjects\\博客\\10.作用域与命名空间\\作用域.py', '__cached__': None, 'a': 'hello', 'fn': <function fn at 0x000002282E3D7280>, 'b': 'world'}
进程已结束,退出代码0
好啦!以上就是作用域与命名空间,通过这篇文章,之后我们去定义变量和访问变量以及修改变量更加明确了,知道什么时候该用,什么时候不该用啦~~~