【一】函数的调用方式
【1】直接调用函数
-
函数()----》调用函数
#案例 def name_age(name,age): print(f"my name is {name} and my age is {age}") #方式一调用使用 name_age(name="tom",age=20) #方式二调用使用 name_age("tom",20)
【2】用表达式调用函数
-
用一个新变量储存函数的内存地址然后叠用
#案例 def age(f,p): #返回值 return f+p #表达式调用函数 data = age(2,3) + 6 print(data)#输出11
【3】函数作为返回值
#案例 #一层嵌套一层 def add(f,p):#add(增加,添加) return f+p def delete(a,b):#delete(删除) return add(a,b) def func():#func(函数) return add func_one = func() print(func_one(8,8))#16
【4】函数作为参数传递给另一个函数
# 【3】触发这个函数 带入参数x 参数y def multiply(x, y): # 计算出返回值 return x * y def operate(func, x, y): # 【2】函数地址传过来 带参数过来 # 返回值是 函数地址(参数x,参数y) # 【4】接收到返回值并返回 return func(x, y) # 【1】operate 函数 有3个参数 : 函数地址 参数x 参数y result = operate(multiply, 4, 6)#multiply(乘)operate(操作,运转) # 【5】拿到返回值 print(result)
【二】函数的参数
【1】形参和实参
(1)形参:
-
就是在函数定义阶段()后面里面的参数
-
函数调用的时候传递进去,这个参数只能在当前函数内部生效
(2)实参:
-
调用函数的时候传进去那个真实的值
-
可以按照位置和关键字传递参数
-
-
实参可以使用表达式,常量,变量
【1】按照位置传参
-
位置传参就要按照位置传参,位置错乱就会导致程序错乱
【2】按照关键字传参
-
关键字传参的时候,要指定函数定义时的位置参数名
-
允许按照关键字传参数,并且指定上关键字
-
允许不按照位置传参,指定上关键字即可
【3】关键字和位置参数连用
-
连用的时候位置参数一定要在关键字传参之前
#位置参数,不可换位置,关键字参数可以换,不可换在位置参数之前 def func(name,age,hobby): print(f"my name is {name} my age is {age} my hobby is {hobby}") func("tom", age=18,hobby = "music") func("tom",hobby = "music", age=18)
【2】默认参数
-
函数定义阶段函数()后面可以定义默认值
-
位置参数给了默认值之后,在函数调用的时候,可以不指定默认参数的值,不给值默认就是默认值
-
意思就是写函数的时候()里面给的有默认值调用的时候函数()后面可以不写
-
如果给了值就会把原来的覆盖
-
#案例 def func(name,age=17,hobby ="dance" ): print(f"my name is {name} my age is {age} my hobby is {hobby}") func("tom", age=28,hobby = "music")#重新换值就会把原来的覆盖 #my name is tom my age is 28 my hobby is music
''' # num_list 可变数据类型 ---> 定义一次下一次修改列表会影响到原来列表 def app_list(num, num_list=[]): num_list.append(num) print(num_list) app_list(1) app_list(2) app_list(3) # [1,2,3] ''' ''' # num_list 每一次调用函数都是一个新的列表所以值只会是最后一个 def app_list(num): num_list = [] num_list.append(num) print(num_list) app_list(1) app_list(2) app_list(3) ''' ''' num_list = [] def app_list(num): global num_list num_list = [] num_list.append(num) app_list(1) app_list(2) app_list(3) print(num_list) '''
【3】可变长位置参数
(1)什么是可变成位置参数
-
可变长位置参数接收到多余的位置参数放到一个元组中
-
可变长位置参数可以用一个变量来接收所有超出指定参数的位置参数
-
在函数定义的时候再形参位置添加*args用来接收多余的位置参数(args(参数)是可以自己指定的)
def student(name, age, gender='male', *pppp): print(name)#dream print(age)#18 print(gender)#male print(pppp)#(999, 888, 666) student('dream', 18, 'male', 999, 888, 666) # 解包语法 : * + 可迭代类型 就能将每一个元素单独解包出来 name = "tom" print(*name)#t o m num_list = [1,2,3,4,5,6,7,8,9,10] print(*num_list)#1 2 3 4 5 6 7 8 9 10 num_list_tuple = (1,2,3,4,5,6,7,8,9,10) print(*num_list_tuple)#1 2 3 4 5 6 7 8 9 10 def student(name, age, gender='male', *pppp): print(name)#dream print(age)#18 print(gender)#male print(pppp)#(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) num_list = [1,2,3,4,5,6,7,8,9,10] student('dream', 18, 'male', *num_list)
-
解包语法 : * + 可迭代类型 就能将每一个元素单独解包出来
【4】可变长关键字参数
(1)什么是可变长关键字参数
-
可变长关键字参数接收到多余的关键字参数放到一个字典中
-
** + kwargs
def student(name, age, gender, *args, **kwargs): print(name, age, gender) # dream 18 male print(f'args :>>>> {args}') # args :>>>> (888, 666) print(f'kwargs :>>>> {kwargs}') # kwargs :>>>> {'class_id': 2, 'addr': '上海'} student('dream', 18, 'male', 888, 666, class_id=2, addr='上海')
-
字典支持 * 解包 ,解包后得到的结果是 字典的每一个键
-
字典不支持 ** 解包
user_data = {'username': "dream", 'password': "521"} print(*user_data)#username password #**会报错
【5】命名关键字参数
-
在定义了
**kwargs
参数后,函数调用者就可以传入任意的关键字参数key=value -
如果函数体代码的执行需要依赖某个key,必须在函数内进行判断
def register(name, age, **kwargs): if 'sex' in kwargs: # 有sex参数 pass if 'height' in kwargs: # 有height参数 pass
-
*后面的就是命名关键字参数
-
*之前的位置参数支持位置和关键字传参数
-
*后面的参数必须按照关键字传参数
#案例 #在位置参数中间指定 * 隔开 def student(name, age, gender,*, class_id, addr): print(name, age, gender, class_id, addr) student('dream', 18, 'male',class_id= 2, addr='上海') # 在命名关键字参数中指定默认参数的时候,默认参数允许放在位置参数之前 # 但是普通的位置参数是不允许关键字参数放在位置参数之前的 ''' def student(name, age, gender='male',*, class_id=2, addr): print(name, age, gender, class_id, addr) student('dream', 18, 'male',class_id= 2, addr='上海') '''
【6】混合使用
-
综上所述所有参数可任意组合使用,但定义顺序必须是:
-
位置参数
、默认参数
、*args
、命名关键字参数
、**kwargs
-
-
可变参数
*args
与关键字参数**kwargs
通常是组合在一起使用的 -
如果一个函数的形参为
**args
与**kwargs
,那么代表该函数可以接收任何形式、任意长度 -
所有位置参数、默认参数、*args 、**kwargs 混合使用的时候不允许使用关键字参数
-
def student(name, age=18,*args,**kwargs):
-
所有位置参数、默认参数、*args 、kwargs , kwargs 必须在 *args 之后