疫情环境下的网络学习笔记 python 3.19
3.19
回顾
- 
python中所有传递的值,都不是值本身,而是值的引用,即内存地址,所以也称作引用传递 
- 
函数两大类:内置函数,自定义函数 
- 
什么是形参,什么是实参: 实参:变量值,形参:变量名 
- 
位置形参:从左到右依次写下来,必须被传值 
- 
默认形参:定义阶段已经为其赋值,调用的时候可以不用被其赋值。默认形参赋值的内容应该是不可变的 函数的运行不应该受外界代码的干扰 需求默认形参是可变值的时候可以默认赋值为none,再在函数体内判断 
- 
位置实参:从左到右顺序,一一对应传给对应的位置形参或默认形参 
- 
关键字实参:可以打乱顺序,指名道姓地对一个形参赋值 必须在位置实参后面,不能重复对形参赋值 
- 
,* 在形参中,可以接收溢出的位置实参和溢出的关键字实参 溢出的位置实参保存成元组赋值给 *args,溢出的关键字实参保存成字典赋值给 **kwargs 
- 
*,**在实参中用于打散,*打散一个个元素,分别跟位置形参对应 **打散字典成关键字实参 
- 
# 很重要 def index(x,y,z): print(x,y,z) def wrapper(*args,**kwargs): index(*args,**kwargs) wrapper(1,y=2,z=3) # x:溢出的位置实参,转成元组传入args。y,z:溢出的关键字实参,转成字典传入kwargs # index中 *将args打散,元组转回成x,**打散kwargs,字典转回成关键字 # 最终wrapper的格式会转嫁给index将本来传给wrapper的格式原封不动地传给其中调用的函数index 给wrapper传的参数格式要遵循 index的参数格式 
今日内容
- 
函数参数补充 命名关键字参数 组合使用 
- 
名称空间与作用域 三种名称空间的用途与生命周期 三种名称空间的加载顺序 三种名称空间查找名字的优先级 
- 
作用域 global local 嵌套使用的情况下,作用域与名字的查找关系 
- 
函数对象 
- 
闭包函数 
正课
命名关键字参数
在定义函数时,* 后面的参数,如下所示,称之为命名关键字形参
def func(x,y,*,a,b): # a,b为命名关键字参数
	print(x,y)
	print(a,b)
    
func(1,2,a=1,b=2)
- 
命名关键字实参必须按照 key = value的形式为其传值 强制让函数的使用者用key = value格式传值 
- 
在定义的时候给命名关键字参数赋默认值,可以在调用的时候不传 
组合使用
形参中定义的顺序:
- 
位置形参,默认形参,*args(溢出的位置形参),命名关键字形参,**kwargs(溢出的关键字形参) def func(x,y=111,*args,z,**kwargs)
实参中调用的顺序:
- 
位置实参,*(),关键字实参,**{} def func(x,y,z,a,b,c): print(x) print(y) print(z) print(a) print(b) print(c) func(111,*(3333,4444),b=555,**{'c':666,'a':222})
名称空间
名称空间是内存中的一个空间,用来存放名字,是对栈区的划分
原来讲的概念里,变量名存放在内存中的栈区。现在将栈区再细分,把同类的变量名分为一片,就是名称空间
划分名称空间后,给所有的名字分门别类存放,且避免了相同的名字被覆盖的情况,可以在不同的名称空间内使用同样的名字不互相冲突
当查找名字的时候,有优先级
全局范围:内置名称空间,全局名称空间
局部范围:局部名称空间
内置名称空间
- 
存放的名字: 存放python解释器内置的名字,内置的函数名,如print,int 
- 
存活周期: python解释器启动则产生,python解释器关闭则销毁 
全局名称空间
- 
存放的名字: 只要不是函数内定义,也不是内置的,剩下的都是全局名称空间 x = 10 # 如定义顶级代码中的变量名 import os #引入的模块名 def func(): # 定义的函数名 class foo: # 定义的类名
- 
存活周期: python程序运行的时候产生,运行完成后销毁 运行python程序刚刚开始运行的时候就产生,在执行到需要存名字的地方,如果名字不是局部或内置,则都丢到全局空间里 
局部名称空间
- 
存放的名字: 
 在调用函数时,运行函数体代码过程中产生的函数内的名字
- 
存活周期: 调用函数时产生,函数调用结束则销毁。可能有多个函数同时运行,所以有多个名称空间同时存在,调用开始创建,调用结束就销毁 调用同一个函数多次,也会产生多个不同的局部名称空间 
加载顺序,销毁顺序
加载顺序:
- 内置名称空间 > 全局名称空间 > 局部名称空间
- 内置和全局一定有,局部不一定有
销毁顺序:
- 局部 > 全局 > 内置
- 先退出函数,再关闭文件,最后关闭解释器
名称空间不是真实存在的东西,像国家,只是用来将名字进行分类。真正用于存放的东西是栈区
名字的查找顺序
从当前所在的位置向上一层一层找
内置         👆
全局         👆
局部2        👆
	局部1    👆
# 名称空间是没有包含关系的,为了便于理解,可以看作包含关系,内置<全局<内置
如果当前在局部名称空间,则先在局部名称空间找,找不到则去全局名称空间找,还找不到最后去内置名称空间找
如果当前在全局名称空间,则先在全局名称空间找,找不到最后去内置名称空间找
最后都找不到,则报错
# 例子
def func():
	input = 111
	print(input)
input = 222	
func()
名称空间的”嵌套“ 关系是以函数定义阶段为准,与调用位置的嵌套关系无关,不是从头顶上找
- 
例1 x = 1 def func(): print(x) # 局部找不到,去全局找,找到x = 1 def foo(): x = 222 func() # 与调用无关,只与定义有关,所以这里x =222 不影响 foo()# 输出 1
- 
例2 函数套用定义的情况 input=111 def f1(): def f2(): # input=333 print(input) # 在局部找不到 input,则去上一层局部找,在f1这一层局部中找到 input=222 input=222 #假如这里也被注释,那么会再去上一层全局名称空间中找,找到 input=111 f2() f1()
- 
例3 x = 111 def func(): print(x) x = 222 # 报错:变量x在定义前被使用 func()
作用域
全局作用域
全局作用域:内置名称空间,全局名称空间
- 全局存活
- 全局有效:被所有函数共享,在无论哪里都可以被访问到
局部作用域
局部名称空间中的名字
- 临时存活
- 局部有效:函数内有效
顺序也可以记为LEGB:
- local,enclosing,global,built in
global与nonlocal关键字
global
如果在局部想要修改全局的名字对应的值(不可变类型),用 global + 全局变量名
x = 111
def func():
	global x  # 声明 x 是全局的名字,不用再在局部造新的名字
	x = 222
	
func()
print(x)
如果不用关键字,则会在局部产生新的值,与上一层的全局变量没有关系
对于可变类型,不需要用这些关键字操作,直接改就行
nonlocal (了解)
当存在局部名称空间”嵌套“的情况
x = 0
def f1():
	x = 11
	def f2():
		nonlocal x
		x = 22
	f2()
	print('f1内的x:',x)
	
f1()
从当层空间的外层开始找关键字之后的变量名,找到最外层的局部名称空间,找到了就操作这个值,找到全局作用域还没找到就报错

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号