【每天1分钟】PYTHON基础之模块(名称空间)
一、名称空间定义:
1.内置名称空间:
源码里面的一些函数都是存在这个内存空间中,任何模块均可访问它,它存放着内置的函数和异常
2.全局名称空间:
当程序运行时,代码从上至下一次执行,他会将变量与值的关系存储在一个空间中,这个空间叫做全局名称空间(名称空间,命名空间)。
名称空间里面存的东西是,变量名与变量的内存地址的对应关系。
————(存的内容如:neame --> 13265654 一个对应关系)
当程序遇到函数时,他会将函数名存在内存中,函数体莫不关心。
————(也就是说全局名称空间,可以存变量名、变量值、函数名、但不存函数体)
3.局部名称空间:
函数外面是访问不到临时空间的内容的,随着函数的执行完毕,临时名称空间会释放掉,像这个临时开辟的空间叫局部名称空间(临时名称空间)。
当函数执行时,内存会临时开辟一个空间,存放函数体里面的代码(变量,代码等)
4. 加载顺序与查找顺序
加载顺序:内置名称空间------>全局名称空间----->局部名称空间
名字的查找顺序:局部名称空间------>全局名称空间----->内置名称空间
二、取出名称空间内容方法:
1. globals() vs locals()
内置函数globals() 全局名称空间内容,字典格式输出
返回一个字典,字典里面的内容是全局名称空间的内容
不论该函数在什么内存空间中,反回的值一直是全局名称空间的所有内容
内置函数locals() 当前作用域空间内容,字典格式输出
反回一个字典,当前位置的所有变量
可以理解为,所在内存空间中的的所有变量,全局内存即显示所有,局部内存显示当前局部内存里的所有变量,在哪个局部内存里就显示哪个内存里的所有变量
>>> from pprint import pprint
>>>
>>> a = 100
>>> b = 4
>>> def foo():
x = 100
print(x)
print('-----------------------------------')
pprint(globals())
print('-----------------------------------')
pprint(locals())
print('-----------------------------------')
>>> foo()
100
-----------------------------------
{'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__doc__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'a': 100,
'b': 4,
'foo': <function foo at 0x0000028949184730>,
'pprint': <function pprint at 0x0000028949184BF8>}
-----------------------------------
{'x': 100}
-----------------------------------
>>>
三、改变上层空间的变量值方法
不可变数据类型修改上层空间变量值的方法:调用内置函数global、nolocal
global作用:(操作全局变量)
1. 应用并改变一个全局变量。
2. 在局部作用域声明一个全局变量。
前提:
在函数取值顺序时有一条,局部空间向全局空间可以引用取值,不能改变取值,否则会报错!
# 应用并改变一个全局变量
>>> count = 1
>>> def f1():
global count # 引用并改变一个全局变量不会报错
count = count + 1
count = count + 100
print(count)
>>> f1()
102
>>> print(count)
102
>>>
# 在局部作用域声明一个全局变量
>>> def f2():
global name # 局部作用域直接声明一个全局变量
name = '小白TOO爱学习'
print(name)
>>> f2()
小白TOO爱学习
>>> print(name)
小白TOO爱学习
>>>
nonlocal作用:(操作局部变量)
nonlocal不能操作全局变量,只针对局部变量进行修改。
在函数嵌套中,函数从内向外依次取值,向上层函数取值时,都只是引用不能改变。想要改变需要借助nolocal进行修改。
nonlocal在函数嵌套,多层局部变量,从那层引用的该变量,就从那层开始全部改变。
>>> def f2():
count = 1
def inner():
nonlocal count
count = count + 3
print(count) # 打印inner函数作用域的count值
def inner2():
pass
inner()
print(count) # 打印inner上级函数f2作用域的count值
>>> f2()
4
4
>>>
可变的数据类型 list dict set修改上层空间变量值的方法:(不用global nonlocal)
>>> list1 = []
>>> def f3():
list1.append(999)
>>> f3()
>>> print(list1)
[999]
>>>
如果默认参数是一个可变的数据类型,那么他在内存中永远是一个内存地址,一个变都变
>>> def extendList(val,list=[]):
list.append(val)
return list # 结束函数反回值是list
>>> list1 = extendList(10)
>>> print('list1=%s'%list1)
list1=[10]
>>> list2 = extendList(123,[])
>>> print('list2=%s'%list2)
list2=[123]
>>> list3 = extendList('a')
>>> print('list3=%s'%list3)
list3=[10, 'a']
>>>
>>>
>>> print('list1=%s'%list1)
list1=[10, 'a']
>>> print('list2=%s'%list2)
list2=[123]
>>> print('list3=%s'%list3)
list3=[10, 'a']
>>>
给函数传参立马得出结果和传完参数统一打印结果,可以看出可变的数据类型,在内存地址是不会改变的。