函数的进阶
- 传递参数时,可以在序列类型的参数前添加 * 这样会自动将序列中的元素一次作为参数传递;
s = "123" l = [1, 2, 3] t = (1, 2, 3) s1 = {1, 2, 3} d = { "name": "帅帅", "age": 21, "sex": "男" } def fun(arg1, arg2, arg3): print("{} ~ {} ~ {}".format(arg1, arg2, arg3)) fun(*s) # 1 ~ 2 ~ 3 fun(*l) # 1 ~ 2 ~ 3 fun(*t) # 1 ~ 2 ~ 3 fun(*s1) # 1 ~ 2 ~ 3 fun(*d) # name ~ age ~ sex 备注:只会打印字典的 key # fun(**d) # **d 可以输出字典的 value 但是前提要求:字典的key需要和函数的参数名保持一致 d = { "arg1": "帅帅", "arg2": 21, "arg3": "男" } # **d 可以输出字典的 value 但是前提要求:字典的key需要和函数的参数名保持一致 fun(**d) # 帅帅 ~ 21 ~ 男
# args 接受可变参数,元组类型 def fun(num, *args): print(num) print(args) print(type(args)) # <class 'tuple'> fun(100, 200, 300, 400, 500) # 输出 num = 100 args = (200, 300, 400, 500) # 列表|元组|集合的解包 fun(100, *[200, 300, 400, 500]) # 输出 num = 100 args = (200, 300, 400, 500) fun(100, *(200, 300, 400, 500)) # 输出 num = 100 args = (200, 300, 400, 500) fun(100, *{200, 300, 400, 500}) # 输出 num = 100 args = (200, 300, 400, 500) # **kwargs 接收关键字参数,字典类型 def fun(num, **kwargs): print(num) print(kwargs) print(type(kwargs)) # <class 'dict'> fun(100, name="帅帅", age=21, sex="男") # 输出 100 kwargs = {'name': '帅帅', 'age': 21, 'sex': '男'} d = { "name": "帅帅", "age": 21, "sex": "男" } # 字典参数解包,配合普通参数一起使用 fun(100, **d) # 输出 100 kwargs = {'name': '帅帅', 'age': 21, 'sex': '男'}
顺序:位置参数 --> 默认值参数 --> *args 元祖类型可变参数 ---> **kwargs 字典类型可变参数
- 默认参数 + 可变的元祖类型的参数,默认参数的默认值无效;【重点理解】若不传默认参数的值,会将可变参数 *args 的第一个值作为默认的参数值
def fun(num, name = "张三", *args, **kwargs): print(num) # 100 print(name) # 帅帅 print(args) # (1, 2, 3, 4) for data in args: # 可变参数元组的遍历 print(data) print(kwargs) # {'x': 10, 'y': 20, 'z': 30} for key, value in kwargs.items(): # 可变参数字典的遍历 print(key, value) fun(100, "帅帅", 1, 2, 3, 4, x = 10, y = 20, z = 30) # 函数定义 def study(name, startTime, subject="c语言", *args, **kwargs): message = "{}学习{}的开始时间为:{}".format(name, subject, startTime) print(message) print("args = ", args) print("kwargs = ", kwargs) lst = ["2023-10-01", "2023-10-10", "2023-11-10", "2024-02-17"] studyMethod = { "c语言": "老师辅导", "mysql": "视频自学", "python": "书籍自学" } # 函数的调用:若不传默认参数的值,会将可变参数 *args 的第一个值作为默认的参数值 study("帅帅", "2023-09-20", "c语言", *lst, **studyMethod)
def fun(num1, num2): print("num1 = {}, num2 = {}".format(num1, num2)) fun(100, 200) # num1 = 100, num2 = 200
【2】函数执行完只有一个返回值
def sum(num1, num2): return num1 + num2 result = sum(100, 200) print("sum = %d" % result) # sum = 300
【3】函数执行完有多个返回值(使用逗号分隔)
def swap(num1, num2): return num2, num1 # 推荐使用这种方式,明确每个返回值指定对应的接收变量 num1, num2 = swap(100, 200) print("num1 =", num1, "num2 =", num2) # num1 = 200 num2 = 100 # 另一种方式:使用元祖变量,接收多个返回值 t = swap(100, 200) print(t) # (200, 100) print(type(t)) # <class 'tuple'> num1, num2 = t # 元组的解包,也可以这样来写 print("num1 =", num1, "num2 =", num2) # num1 = 200 num2 = 100
def fun(): def test(): return [1, 2, 3] return test # 接收函数类型的返回值 result = fun() print(type(result)) # <class 'function'> # 里层函数的调用 print(result()) # [1, 2, 3] # 或者可以直接写 print(fun()()) # [1, 2, 3]
""" lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。 lambda就是用来定义一个匿名函数的,通常是直接使用lambda函数,不需要绑定一个名字! 简洁大方,一般情况不通用,不对外提供! lambda 表达式:函数体一般情况下简洁明了,lambda 属于关键字,后面紧跟函数需要的参数 语法: 函数名称 = lambda 参数 : 函数的函数体 本质上就是一个函数的另外一种写法,意义:简单明了 """ # 求解两个数的和 add = lambda x, y : (x+y) print(add(1, 2)) # lambda函数应用在函数式编程中 lst = [-1, -3, -5, -7, -9, 2, 4, 6, 8, 10] lst.sort(key=lambda x: abs(x)) # 按照绝对值进行升序排列 print(lst) # 排序也可以这样来使用 lst2 = [-1, -3, -5, -7, -9, 2, 4, 6, 8, 10] result = sorted(lst2, key=lambda x: abs(x)) print(result) # 当然也可以这样来使用,先定义函数,然后传入函数参数即可 def numAbs(x): return abs(x) lst3 = [-1, -3, -5, -7, -9, 2, 4, 6, 8, 10] result = sorted(lst3, key=numAbs) print(result)
""" 1)函数的三大要素:返回值,函数名称,函数的参数 函数的返回值,根据函数调用完成之后才确定,可以返回任意数据类型,根据实际的场景自行实现; 函数名称:不能是关键字 函数的参数:位置参数,默认参数,关键字参数; 可变参数(元祖类型的可变参数 *args)(字典类型的可变参数 **kwargs) 定义函数时,要使用关键字 def 2)位置参数:【函数的定义方】 位置参数接受的值可以是任意类型:数字(int float bool)字符串,元祖,列表,字典,集合 位置参数需要和调用函数传递的参数一一对应,若缺少则报错(和C语言一样) 3)默认参数:【函数的定义方】 给函数的形式参数赋默认值; 调用方若没有传默认参数的值,则取默认值,否则取传递的值 4)关键字参数:【函数的调用方】 例如:a = 1,b = 2,c = 3 关键字参数的名称需要和函数的定义方形式参数的名称保持一致,若不一致则报错 5)可变参数 *args:【函数的定义方】 可变参数的类型为元祖的类型,不可变,使用 () 表示 6)可变参数 **kwargs:【函数的定义方】 可变参数的类型为字典的类型,可变,使用 {} 表示 传递的参数形式:关键字参数的传递形式,但是需要注意: 若传递关键字参数的名称和函数定义方的名称一致,就不会传递给可变参数 **kwargs,而且摆放是无序 7)lambda 表达式: 简单明了,一般情况下,函数体只有一行,本质上还是一个函数,另外一种写法而已 语法:函数名称 = lambda 参数 : 函数的函数体 注意:函数的定义方参数的顺序一般为: 1位置参数 ---> 2默认参数 ---> 3可变参数 *args 元祖类型 ---> 4可变参数 **kwargs 字典类型 若默认值参数 + 可变参数 *args 默认值参数无效(若不传默认值参数,可变参数的第一个值会默认传值); 若默认值参数 + 可变参数 **kwargs 默认值参数生效(若不传默认值的参数,则取函数定义的默认值参数的值) """