一.函数的进阶
1.1 动态参数
1.2* **
1.3*args , **kwargs
1.4 函数的注释
1.5名称空间
1.6函数的嵌套
全局变量 : 贴边写的
局部变量 : 不是贴边写的。
''' 函数执行流程: 1.定义函数 2.在内存中开辟地址空间 3.调用函数 4.执行函数体 5.销毁函数开辟的内存空间 '''
1.1动态参数
静态
def func(): # 形参 pass func() #实参
#不确定 变化的 动态位置参数
def func(a,b,c,*args ): #在形参位置*叫做聚合 print(args) #元组形式 func(1,2,3,4,5,6,7,8,9)
#位置参数》动态的位置参数 》默认参数》动态(关键字)默认参数
错误用法:
#*args 在前 后面的不能得值 出错 #TypeError: func() missing 3 required keyword-only arguments: 'a', 'b', and 'c' # def func(*args , a, b,c): # 在后可以! 和 a =1 一样出错的吗
动态默认参数
def func(**kwargs): #动态默认参数 print(kwargs) #字典 func(a=1, b=2, c=3) #关键字的形式传参
# args 和 kwargs 是可以更换的,但是程序员约定用它
#在不明确 接受参数 数量时 使用 *args **kwargs
总的写法:
def func(*args , **kwargs): print(args , kwargs) func(a = 1, b=1 , c= 1)#() {'a': 1, 'b': 1, 'c': 1} # func(a = 1, b=1 , c= 1 ,1,2,3,4)# error func(1,2,3,4 , a = 1, b=1 , c= 1 )# (1, 2, 3, 4) {'a': 1, 'b': 1, 'c': 1}
#四个 一起的位置顺序 形参 实参 是两个
#位置参数必须得有值 一一对应 # def func(a,b,c,*args ,x ,y , **kwargs): #error: 没对应 def func(a,b,c,*args ,x = 1 ,y =1 ,**kwargs): # def func(a, b, c, *args, **kwargs , x=1, y=1): #SyntaxError: invalid syntax print(a,b,c) print(x,y) print(args , kwargs) # print(**kwargs) # func(1, 2, 3, 4, a=1, b=1, c=1) # a,b,c 不行 重复变量 func(1, 2, 3, 4, 5, e=1, d=1, f=1) # (4,) {'e': 1, 'd': 1, 'f': 1} #形参(在前): 位置> 动态位置> =默认参数(也可以出来) >动态默认参数 #实参: 位置> 关键字参数
1.2* 实参是打散 *形参是聚合
def func(*args , **kwargs): # 聚合(1,2,3) print(*args , *kwargs) #* 打散 1 2 3 func(1,2,3,e=1) li = [1,2,3,4] def fuc(*args): print(args) print(*args) # func(li) # 先[1,2,3,4] func(*li) #先打散 1,2,3,4
1.3
'''
在实参调用的时候 *是将可迭代的对象打散,(字典是将键取出)**就是将关键字参数聚合成一个字典
在形参处 出现 * 就是在聚合() 和 **字典打散成键=值 在函数中第一次出现是 打散 第二次出现 聚合
'''
dic = {'a' :1 , 'b':2} def func(*args , **kwargs): print(args,kwargs) # 给args 如果给了就是字典() {'a': 1, 'b': 2} print(args, *kwargs) # 给args 给了的话是 键() a b print(args,**kwargs) # 出错 不可以打印 此种格式print(a = 1, c=2) # func(*dic) #func(*可迭代) #func(*[1,2,3]) func(**dic)#给了kwargs#func(a = 1 , b= 2)
def func(a):#返回值 **twargs
print(a)
func(**{'a':1})
1.4 函数的注释
官方推荐‘’‘’‘’‘’‘’‘’
----------便于合作
def login(user, pwd): ''' 登录函数 :param user: 用户 :param pwd: 密码 :return: 校验后的帐号和密码 ''' print(111) print(login.__doc__)# 文件内容 # 返回文件名 __shenme__ print(login.__name__) 数据库__doc__ 把等于化成 字典格式
'''
1.5名称空间
1.内置空间中的所有代码 ---内置空间
2.自己写的文件 ---全局空间
3.函数中的代码 ---局部空间
'''
#加载顺序:
'''
内置空间
全局空间
局部空间
'''
#查找值的顺序
'''
1.局部空间
2.全局空间
3.内置空间
4.找不到就报错
''' #可以查找值,但是不可以改值 所以有: gal no
a = 10 def func(): a = 1 print(a) func()
#作用域
'''
1.全局作用域 内置+全局=全局作用域
2.局部作用域 函数内的就是局部作用域
'''
#global : 在局部修改全局变量,如果没有就创建一个新的 只操作全局
a = 10 # print(id(a)) def func(): # print(id(func)) # a = 1 # a += 1 global a #找到要修改的值,修改完重新放回 print(id(a)) #地址 不同 付给他的吗? a += 1 #可以改值?但是作用域作用不出去 没法赋值给a? # print(id(a)) print(a , id(a))#10 490696448 func() print(a , id(a)) #11 490696480 此a 非彼a print(id(a))
#1.6函数的嵌套
#方式1 在函数func 内
def func1(): print(3) def f(): # 没执行 定义了 只打印32 print(1) print(2) # f() #321 func1()
# 方式2 多个函数嵌套调用
def func2(): print(1) log() # func2() # error def func3(): print(1) def log(): func3() print(1) func2() #启动口 前面是定义开辟空间
3'''nonlocal 操作局部 函数里
在一个局部全局内,nonlocal 会修改离他最近的那个
变量,如果上一层没有就继续上找,知道找到局部空间头部
''' #没有找到就报错
def func(): a =1 def log(): a =5 def info(): # global a nonlocal a #重新放回去 a+=10 # 5+10 =15 print(a) info() print(a) #15 log() print(a) func()
def f(): a = 1 print(id(a)) def a(): a = 5 print(a) print(a) #直接打 函数的地址 不是1 print(id(a)) f()
def f(): a = 1 print(a) def a1(): a= 5 print(a) def l(): nonlocal a a = 8 print(a) l() print(a) print(a1()) f()
老师说,排bug 从下往上 读 从上往下 花时间在理思路?
#从最里层返回任意一个字符串,在最外层打印
def fua(args): def fub(args): def fuc(args): def fud(args): a = 8 return a a = fud(0) return a a = fuc(0) return a a = fub(0) return a print(fua(0))
a = 10 def outer(): a = 20 def inner(): #在内层函数中使用和全局变量同名的变量 #1.直接使用 #2.更改 #如果直接使用一个变量,默认是全局,不能在内层函数中对全局变量进行更改 #python中使用global 关键字指定全局变量 进行更改和使用 print('a') global a # a = 100 print(id(a)) print(a) a = 100 inner() outer()
def wrapper(): def inner(): print(666) # 直接调用 # inner() # 把函数定义返回 # 不要加() return inner fun = wrapper() # # fun就是函数名了 # 相当于 def fun() ------- fun()
#() 调用操作符
#[] 索引操作符