一、函数/方法【重点掌握】
1.函数基本使用:
定义
调用
参数
返回值
匿名函数
2.函数进阶使用
闭包
变量的作用域
高阶函数
装饰器【难点,重点】
递归
函数:function
方法:method
1.概述
在一个完整的项目中,某些功能可能会被反复使用,如果将反复出现的代码封装成函数,以后如果要继续使用该功能则直接使用函数即可,另外,如果要修改需求,只需要修改函数
本质:对某些特殊功能的封装
优点:
a.简化代码结构,提高应用的模块性
b.提高了代码的复用性
c.提高了代码维护性
# 需求:求圆的面积 # 1. r1 = 45 area1 = 3.14 * r1 ** 2 print(area1) r2 = 10 area2 = 3.14 * r2 ** 2 print(area2) r3 = 5 area3 = 3.14 * r3 ** 2 print(area3) # 2.优化 # 本质:对某些特殊功能的封装 def area(r): return 3.14 * r ** 2 print(area(45)) print(area(10)) print(area(5)) """ 优点: a.简化代码结构,提高应用的模块性 b.提高了代码的复用性 c.提高了代码维护性 """
2.定义
语法:
def 函数名(变量1,变量2…):
函数体
return 返回值
说明:
a.def是一个关键字,是definition的缩写,专门定义函数
b.函数名:遵循合法标识符的规则和规范即可,尽量做到见名知意
c.(变量1,变量2…):被称为形式参数,是一个参数列表,都只是没有赋值的变量
d.函数体:封装某些特殊的功能
e.return是一个关键字,表示返回,只能用在函数中,表示结束函数,可以单独使用,也可以携带数据,当携带数据,则表示该函数的返回值
f.返回值:常量,变量,表达式
g.函数的定义分为两部分:函数的声明和函数的实现
h.变量1,变量2… 和 return 返回值 可以根据具体的需求选择性的省略
""" 语法: def 函数名(变量1,变量2....): 函数体 return 返回值 说明: a.def是一个关键字,是definition的缩写,专门定义函数 b.函数名:遵循合法标识符的规则和规范即可,尽量做到见名知意 c.(变量1,变量2....):被称为形式参数,是一个参数列表,都只是没有赋值的变量 d.函数体:封装某些特殊的功能 e.return是一个关键字,表示返回,只能用在函数中,表示结束函数,可以单独使用,也可以携带数据,当携带数据,则表示该函数的返回值 f.返回值:常量,变量,表达式 g.函数的定义分为两部分:函数的声明和函数的实现 h.变量1,变量2.... 和 return 返回值 可以根据具体的需求选择性的省略 """ print("start") # 1.基本语法 # a.函数的声明部分 def test(): # b.函数的实现部分 print("1111") # 2.函数不同形式的定义 # a.无参无返回值的函数 def func1(): print("func~~111") # b.有参无返回值的函数 def func2(a,b): print("func~~~~~222") # c.无参有返回值的函数 def func3(): return "abc" # d.有参有返回值的函数 def func4(num1,num2): return num1 + num2 print("end") """ 总结: a.函数和if语句,while循环,以及for循环相似,都是代码块的操作 b.定义函数的过程相当于定义变量的过程,只是将函数加载到了内存中 c.一个函数一旦定义完成,则需要手动调用,否则不会执行 """
3.调用
""" 函数的定义: def 函数名(形式参数): 函数体 return 返回值 函数的调用: 函数名(实际参数) 形式参数:出现在函数的声明部分,简称形参,可以理解为是一个等待赋值的变量 实际参数:出现在函数的调用部分,简称实参,实参就是给形参赋值的数据 调用函数的过程实际上就是传参的过程 传参的过程:实参给形参赋值的过程,如果没有形参,则也没有实参,二者需要匹配 """ # 1. print("start") def func1(): print("func~~111") func1() func1() func1() func1() func1() func1() print("end") # 函数调用的工作原理:代码从上往下依次执行,一旦遇到函数的调用,则去执行相应的函数, # 当函数执行完毕,则程序回到函数调用的位置接着执行后面的代码 # 系统函数的调用 list1 = [34,6,7] list1.append(10) list1.insert(1,66) # 2. def func1(): print("111") func2() def func2(): func3() print("222") def func3(): func4() print("333") def func4(): print("444") func1() """ 注意:在py文件中可以直接调用函数, 函数之间也可以相互调用 """ # 3.错误操作 # a.函数自己调用自己,恶性调用 # def test(): # print("ok") # test() # test() # b.两个函数之间相互调用,恶性调用 # def test1(): # print("111") # test2() # def test2(): # print("222") # test1() # test1()
4.参数
4.1参数分类
形式参数:简称形参,定义在函数的声明部分,本质是一个没有值的变量,用于接收实参的值
实际参数:简称实参,出现在函数的调用过程中,本质是一个有值的变量或者常量,用于给形参赋值
传参:实参给形参赋值的过程
参数分类:
必需参数
默认参数
关键字参数
不定长参数【可变参数】
# 1.必需参数 # a.注意1:必需参数传参的时候,一定要注意数量的匹配 def func1(): print("func~~~1111") func1() # func1(34) # TypeError: func1() takes 0 positional arguments but 1 was given # b def func2(a): print("func~~~222",a) # func2() # TypeError: func2() missing 1 required positional argument: 'a' func2(10) func2("abc") # c.注意2:必需参数传参的时候,一定要注意顺序的匹配 def func3(name,age): print(f"姓名:{name},年龄:{age}") # func3(18,"jack") func3("jack",18) # d.注意3:必需参数传参的时候,一定要注意类型的匹配 def func4(name,age): print("姓名:%s,年龄:%d" % (name,age)) # func4("aaa","gahjg") # TypeError: %d format: a number is required, not str func4("张三",10) print("*" * 30) # 2.默认参数 # a.注意1:默认参数体现在形参上 def test1(a,b = 0): # a是一个必需参数,b是一个默认参数 print(a,b,a + b) # 注意2:形参使用默认参数,如果实参给该参数未传参,则使用默认值 test1(3) test1(3,5) # 5会给b重新赋值 # b. def test2(a = 0,b = 0,c = 0): print(a,b,c) test2() test2(2,6) test2(3,4,6) def test3(a,b = 0,c = 0): print(a,b,c) test3(6) def test4(a,b,c = 0): print(a,b,c) test4(6,3) # 注意3:如果形参有多个,可以必需参数和默认参数混合使用,但是在形参中,默认参数靠后书写 # def test4(a,b = 0,c): # SyntaxError: non-default argument follows default argument # print(a,b,c) # test4(6,3) # 注意4:默认参数出现的意义就是为了简化函数的调用 # end默认值为\n print(45) print(60) # print(34,end="*") # 3.关键字参数 # 注意1:关键字参数体现在实参中 def check1(name,age,score): print(f"姓名:{name},年龄:{age},成绩:{score}") # check1("jack",18,100) # check1(18,"jack",100) # 逻辑不通,姓名:18,年龄:jack,成绩:100 # 注意2:使用关键字参数传参可以不用匹配顺序,但是,关键字需要和形参的变量名保持一致 check1(age=18,name="jack",score=100) # 姓名:jack,年龄:18,成绩:100 # check1(age=18,name1="jack",score=100) # TypeError: check1() got an unexpected keyword argument 'name1' check1('aaa',score=88,age=10) check1("bbb",12,score=99) # 注意3:在实参中,关键字参数只能书写在参数的后面 def check2(name,age,score): print(f"姓名:{name},年龄:{age},成绩:{score}") # check2(name="tom",10,66) # SyntaxError: positional argument follows keyword argument # check2(10,66,name="tom") # TypeError: check2() got multiple重复 values for argument 'name' # 注意4:默认参数和关键字参数可以结合使用 def check3(name,age,score=0): print(f"姓名:{name},年龄:{age},成绩:{score}") check3("jack",10) check3("jack",10,67) check3(name="jack",age=10,score=67) check3("jack",age=10,score=67) check3("jack",10,score=67) print("*" * 30) # 4.不定长参数/可变参数:可以接受不定长的参数 # a.*xxx, # 注意1:*xxx,xxx被当成一个元组处理 def text1(*num): print(num) text1() text1(34) text1(34,56,67,68,7,8) text1(34,56,67,68,7,8,"abnfa",True) # 注意2:必需参数可以和不定长参数混合使用 def text2(num1,*num2): print(num1,num2) text2(10,45,56,67,6,8,7,8) # 注意3:如果不定长参数出现在形参列表的前面,则可以结合关键字参数完成传参 def text3(*num1,num2): print(num1,num2) # text3(10,45,56,67,6,8,7,8) # TypeError: text3() missing 1 required keyword-only argument: 'num2' text3(10,45,56,67,6,8,7,num2 = 8) # 注意4:*xxx在形参列表中只能被使用一次 # def text4(*num1,*num2): # print(num1,num2) # text4(45,57,6,77,8) print("*" * 30) # b.**xxx # 注意1:**xxx,xxx会被当做字典处理 def f1(**num): print(num) # 注意2:给**xxx的形参传参,则必须以key=value的方式传参 f1(x=10,y=20,z=30) # {'x': 10, 'y': 20, 'z': 30} # 注意3:**xxx在同一个函数的形参中只能出现一次 # def f2(**num1,**num2): # print(num1) # f2(x=10,y=20,z=30) # 注意4:*xxx和**xxx可以同时使用,但是,分别只能使用一次 def f3(*num1,**num2): print(num1,num2) f3(45,45,65,7,67) f3(45,45,65,7,67,a=4,b=467,fag="abc") f3(a=4,b=467,fag="abc") # 注意5:一般情况下,如果*xx和**xxx结合使用,命名为:*args,**kwargs
4.2参数传递
# 参数的传递:值传递和引用传递 """ 【面试题】简述值传递和引用传递的区别 值传递:传参的时候,传递的是不可变的数据类型,如:int/float/str/tuple/bool,当形参发生修改,对实参没有影响 引用传递:传参的时候,传递的是可变的数据类型,如:list/dict/set等,当形参中的元素发生修改,则实参会随着修改 """ # 1.值传递 def func1(num): print(f"修改之前,num的地址:{id(num)}") num = 100 print(f"修改之后,num的地址:{id(num)}~~~~") temp = 45 func1(temp) print(f"temp的值:{temp}") print("*" * 50) # 2.引用传递 def func1(num): print(f"修改之前,num的地址:{id(num)}") num[1] = 100 print(f"修改之后,num的地址:{id(num)}~~~~") temp = [2,3,4] func1(temp) print(f"temp的值:{temp}")