#Python基础之函数参数
函数参数根据声明方式分为必须参数、默认参数、可变参数、关键字参数、命名关键字参数
同时还可以根据参数的数据类型分为一般数据类型、引用数据类型、函数数据类型(回调函数)
##根据声明方式分类
###1.必须参数
必须参数:程序执行过程中必须要设置的参数。
# 求最大值,num1和num2不可省略、且必须是两个参数
def max_num(num1, num2):
print(max(num1, num2))
max_num(12, 13)
# 13
max_num(12)
# TypeError: max_num() missing 1 required positional argument: 'num2'
max_num(12, 13, 14)
# TypeError: max_num() takes 2 positional arguments but 3 were given
###2.默认参数
默认参数:程序运行过程中具有默认值的参数。
默认参数和必须参数的区别就是参数是否提取设置好默认值,默认参数在函数调用的过程中人为可以省略
默认参数需要放在必须参数后面
def outPut(num=0):
print(num)
outPut()
# 0
outPut(100)
# 100
###3.可变参数
可变参数的语法结构:在必须参数前面添加*
,此时参数就变成了可变参数
可变参数的作用:参数的多少可以根据函数在调用过程中实际参数的数量灵活增长,注意可变参数对应的数据类型是一个元组类型
可变参数需要放在默认参数后面
# 定义函数求任意个数值的和
def get_sum(*arguments):
sum_num = 0
for item in arguments:
if isinstance(item, list):
sum_num += sum(item)
else:
sum_num += item
return sum_num
num = get_sum(10, [1, 2, 3, 4, 5],10)
print(num)
# 35
###4.命名关键字参数
命名关键字参数:在所有参数的最前面设置一个*
,此时后面所有参数都被看成是提取定义好名字的参数。外界在调用该函数时,每个参数的名字必须和*后面的参数名字保持一致。
如果之前有可变参数*args
,则命名关键字参数不需要再次加*
命名关键字参数需要在可变参数之后
def put( *,num1,num2,num3):
print(num1,num2,num3)
put(num1 = 20, num2 = 30, num3 = 40)
# 20 30 40
###5.关键字参数
关键字参数:在必须参数前面加上**
,此时参数变成关键字参数,外界在调用该函数时必须为每一个数据设置一个唯一的键,或者通过**dict
的格式直接将某个字典类型数据作为该关键字参数的数据输
关键字参数处于所有参数之后
# 定义一个函数,利用关键字参数输出一个学生的自我介绍信息(姓名、年龄、性别、婚姻状况、专业、班级、学校)
def outPut_student(**kw):
stInfo = "我叫{name},今年{age}岁,性别{sex},{marriage},毕业于{school} {major}专业 {class}".format(**kw)
print(stInfo)
info = {"name": "狗蛋", "age": 20, "sex": "男", "school": "蓝翔技术学院", "major": "挖掘机炒菜", "class": "挖掘机1班", "marriage": "未婚"}
outPut_student(**info)
# 我叫狗蛋,今年20岁,性别男,未婚,毕业于蓝翔技术学院 挖掘机炒菜专业 挖掘机1班
注意:参数排列顺序为 必须参数----默认参数----可变参数----命名关键字参数----关键字参数
##根据数据类型分类
###1.普通类型作为参数
一般参数常用类型,包括整数、浮点数、字符串等
# 定义一个函数输出任意一个给定的数据
def fun(x):
x += 20
print(x)
x = 20
fun(x)
print(x)
# 40
# 20
上面的一段代码中两个x分别代表实际参数和形式参数,注意函数在调用过程中普通类型的实际参数的数据在传递给形式参数的过程中是一个拷贝的过程,因此在函数内部对形式参数所做的所有数据操作都不会影响实际参数的数据
###2.引用数据类型作为参数
包括元组、列表、集合、字典、对象等引用类型数据结构
引用数据类型作为函数参数被传入到函数内部时,在函数内部所做的操作等价于直接对该数据本身做操作。
引用数据类型的实际参数在传递给形式参数时同样是一个拷贝过程,这里的拷贝指浅复制,虽然生成两个对象,但引用类型指向的对象仍然是同一个(具体见Python基础之直接赋值、浅复制、深度复制),因此在函数内部所做的操作等价于直接对该数据本身做操作
# 定义一个字典,在字典中存储一个人的名字,同时定义函数,完成对该人名的修改
dic = {"name": "zhangsan"}
def change_name(dic):
dic["name"] = "lisi"
print(dic)
change_name(dic)
print(dic)
# {'name': 'lisi'}
# {'name': 'lisi'}
###3.函数作为参数
函数作为函数参数传入函数内部,此时传时函数内部的函数被称为回调函数
比如函数B作为函数A的参数传入到A内部,在A内部调用函数B,此时B函数被称为回调函数
回调函数的作用:可以将一些不确定的操作交给使用者来实现,从而实现代码功能的扩充
# 定义一个函数,完成对列表数据的遍历,并且对每一次遍历结果做任意处理
# 管理者定义
def map_list(list1,callBack):
list1 = list(list1)
for i in range(len(list1)):
result = callBack(list1[i])
if (isinstance(result, str) and len(result) == 0) or result is None:
list1[i] = None
else:
list1[i] = result
while None in list1:
list1.remove(None)
return list1
# 使用者定义
# 功能1:提取数字
def cordination_1(num):
if isinstance(num, int):
return num
else:
return None
# 功能2:提取非数字
def cordination_2(num):
if isinstance(num, int):
return None
else:
return num
# 功能n:任意定义
# 使用者\用户调用
print(map_list([4, 2, 5, "f", "A", " "], cordination_1))
# [4, 2, 5]
print(map_list([4, 2, 5, "f", "A", " "], cordination_2))
# ['f', 'A', ' ']