1,动态参数(形参):顾名思义就是这个参数是时刻在变化的,动态格式: *函数名 =动态参数,列如:(*food)
1>位置参数的动态参数:*args()能接收任意的位置参数.
列如:def func(*args)..................................................他接受所有的位置参数
print("我喜欢:",args)
func("李智恩","陈乔恩","宋慧乔","吴宣仪")..........此时打印的结果是:我喜欢:("李智恩","陈乔恩","宋慧乔","吴宣仪")此时返回一个元组
列如:def func(*args,a,b)
print("我喜欢:",args,a,b)
func("李智恩","陈乔恩","宋慧乔","吴宣仪").......此时报错,因为这是的位置参数都被动态参数接收了,到位参a,b的时候就没有参数了,函数就调用不起来了,程序运行失败
#.....动态参数接收数据时必须放在位置参数的后边.
默认参数:
列如:def func(a,b,c="李子璇",*args):
print("我喜欢:",a,b,c,args)
func("李智恩","陈乔恩","宋慧乔","吴宣仪")..............此时打印结果是:我喜欢:"李智恩","陈乔恩","宋慧乔",("吴宣仪,")
func("李智恩","陈乔恩",)...........................................此时打印的结果是:我喜欢:"李智恩","陈乔恩","李子璇"()...空的元组,因为没有值给它
func("李智恩","陈乔恩","宋慧乔").............................此时打印的结果是:我喜欢:"李智恩","陈乔恩","宋慧乔"().....空的元组,同样没有值给它
func("李智恩","陈乔恩","宋慧乔","吴宣仪","赵丽颖")......此时打印的结果是:我喜欢:"李智恩","陈乔恩","宋慧乔",("吴宣仪","赵丽颖")
#由此可见:当默认参数在动态参数前边时,只有一种情况默认值才会产生.
#....当位置参数>动态参数*>默认参数时,默认值参数始终生效(当给默认值参数关键字参数时,默认参数失效)
2,动态接收关键字参数,用**来接收动态关键字参数.
2.1>列如:def func(**kwargs):
print(kwargs)
func(a=1,b=2,c=3).............................................此时打印的结果是:{"a":1,"b":2,"c":3}返回的是一个字典
2.2>列如:def func(a,**kwargs,b):
print(a,b,kwargs)
func(1,2,3)..................................................此时打印的结果是:1,:2,{"c":3}返回的是一个字典和2个元素
func(1,b=2,3)...........................................此时报错,位置参数和关键字参数混乱
func(a=1,b=2,c=3).................................此时打印的结果是:1,:2,{"c":3}返回的是一个字典和2个元素
#顺序是:位置参数>*args>默认值参数>**kwargs
#*args接收任意的动态位置参数
#**kwargs接收的是动态关键字参数
2.3>list和dict和字符串的传参:调用函数的时候func(*list/*dict/*s(s="帅爆太阳的男人"))...................把相应的list/dict/字符串拍碎放到元组里
列如:def func(*args):
print(args)
lst = ["帅","爆","太","阳","的","男","人"]
dic = {1:"帅",2:"爆",3:"太",4:"阳",5:"的",6:"男",7:"人"}
s = "帅爆太阳的男人"
func(*lst).........把lst拍碎放到一个新的元组中,打印结果是:("帅","爆","太","阳","的","男","人"),实质是把lst中的每一个元素迭代放到元组中
func(*dic).........把di拍碎放到一个新的元组中,打印结果是:(1,2,3,4,5,6,7),实质是把dic中的每一个key迭代放到元组中# 字典拍碎只有key值
func(*s).........把s拍碎放到一个新的元组中,打印结果是:("帅","爆","太","阳","的","男","人"),实质是把字符串中的每一个元素迭代放到元组中
func(*lst,*dic)...把lst中的每一个元素和dic中的key值作为元组放到元组中
补充:当dic中拍碎就用(**dic)拍出来的是键值对.
3,命名空间:在我们定义函数和值之间的关系时,会开辟一个内存空间,这个空间就叫做命名空间.
命名空间的分类:
1>全局命名空间-->我们在.py文件中函数外声明的变量都属于全局命名空间....................python中我们自己的定义函数
2>局部命名空间-->在函数中声明的变量就放在局部你明明空间.......................................python中我们自己的定义函数
3>内置函数空间-->是python解释器中已有的函数命名.....................................................python的内置函数
加载顺序:内置函数空间-->全局命名空间--->局部命名空间(函数调用的时候)
取值顺序:局部命名空间-->全局命名空间-->内置命名空间
3.1>作用域:顾名思义以就是作用的区域(范围),因此分为全局作用域和局部作用域
全局作用域包括:全局命名空间 + 内置函数空间
局部作用域包括:局部命名空间
用globals()来打印全局作用域的内容,locals()是用来查看局部作用域中的内容(变量和值之间的关系)
列如:def func():
a = 40
b = 20
def abc():
print("哈哈")
print(a, b) # 这⾥里里使⽤用的是局部作⽤用域
print(globals()) # 打印全局作⽤用域中的内容 ,,,不是你查出来也看不懂啊有什么用?
print(locals()) # 打印局部作⽤用域中的内容 ,,,同样查出来是乱码看不懂有嘛用?
func()
4,函数的嵌套:调用函数的时候必须用()如果不写那就不调用,在嵌套中最重要的是看调用时那个函数并此时打印的是那个值。
列如:def fun1(): .......................................这个是2个电仪函数的并列关系,就按照从上到下的顺序走就好了
print(111)
def fun2():
print(222)
fun1()
fun2()
print(111) ........................此时最终结果是:222,111,111
列如:def fun2():
print(222)
def fun3():
print(666)
print(444)
fun3()
print(888)
print(33)
fun2()
print(555) .............此时运行最终结果是:33,222,444,666,888,555
分析:当遇到函数的嵌套时,先看母函数(最外边那一层)定义函数名可以先跳过值接从上到下先找(print)或者调用函数()遇到那个就执行那个就好了,当遇到调用的函数内部有子函数时也是***层层降维,从上到下***.
5,关键字global和nonlocal
5.1>global在局部变量中调用全局定义好的变量来重新赋值.
列如:a = 100
def func():
global a # 加了了个global表示不不再局部创建这个变量量了了. ⽽而是直接使⽤用全局的a ,并同时把局部的值从新赋值给从全局变量中拿过来的变量 (全局变量和局部变量必须一致,不然拿不过来)此时的变量就是局部变量赋的值
a = 28
print(a)
func()
print(a)..............................................................................................此时打印的结果是:28,28
5.2>nonlocal表示在局部作用中,调用非本局部中的变量,也不调用全局中的变量.(调用里它最近的一个相同名称的变量)还是"层层降维,从上到下"
列如:a = 10
def func1():
a = 20
def func2():
nonlocal a
a = 30
print(a)
func2()
print(a)
func1()...............................................................此时打印的结果是:30,30