函数(非常重要) - 定义函数、调用函数、函数的参数、函数的返回值、实参高阶函数
面向对象基础
文件操作(text、json、图片文件等) -> 数据库文件、Excel文件、csv文件、PDF、Word
正则表达式
函数的作用
函数存在的价值:当一个功能需要反复使用的时候,如果没有函数,每次需要这个功能就必须把这个功能的代码写一遍。如果有函数,
实现功能对应的代码只需要写一遍(封装成函数),然后在每次需要这个功能的时候调用实现这个功能的函数
def sumN(num):
sum1 = 0
for i in range(1, num + 1):
sum1 += i
print('和:', sum1)
def get_num(str1):
new_str1 = ''
for x in str1:
if x.isdigit():
new_str1 += x
print(new_str1)
认识函数
-
什么是函数(机器)
函数就是实现某一特定功能的代码的封装。
(函数就是将实现某一个或者某类功能的代码打成一个包,以后在需要这个包中的这段代码对应的功能的时候不再重新写这段代码,而是使用封装了这段代码的函数)
-
函数的分类
根据这个函数是由谁创建的,我们将函数分为系统函数和自定义函数两种
1)系统函数(别人已经造好的机器) - 由系统创建的函数(Python本身就创建好的函数),例如:print、input、type、max、min等
2)自定义函数(自己造的机器) - 由程序员自己创建的函数 -
定义函数(造机器)
语法:
def 函数名(形参列表):
函数说明文档
函数体说明:
1)def - 关键字;固定写法
2)函数名 - 由程序员自己命名;
两个要求:是标识符;不是关键字
三个规范:见名知义(看到函数名就大概知道函数的功能是什么);
所有的字母都小写,多个单词用下划线隔开;
不使用系统的函数名、类名和模块
3)(): - 固定写法
4)形参列表 - 以’变量名1,变量名2,变量名3,…'的形式存在,根据情况变量的数据可以为0(每个变量就是一个形参)
形参的作用:将函数外部的数据传递到函数里面。
确定形参的方法:看实现函数的功能需不需要额外的数据,需要多少个额外的数据
5)函数说明文档 - 就是多行注释(相当于生活中机器的说明书)
6)函数体 - 结构上,和def保持一个缩进的一条或者多条语句
逻辑上,函数体就是实现函数功能的代码# 定义一个函数求一个数的阶乘 def factorial(num): """ (功能说明区)求一个数的阶乘:num! :param num: (参数说明)求结成的对象 :return: (返回值说明)None """ sum1 = 1 for i in range(1, num + 1): sum1 *= i print(sum1) # 练习:定义一个函数统计字符串中数字字符的个数 def num_num(str1): """ 统计str1对应的字符串中数字字符的个数 :param str1: 指定字符串 :return: None """ count = 0 for i in str1: if i.isdigit(): count += 1 print(count) num_num('hdajs5456') # 练习2:定义一个函数,将两个字符串中所有的大写字母合并成一个新的字符串 def upper1(str1, str2): """ 将两个字符串中所有的大写字母合并成一个新的字符串 :param str1: 指定字符串1 :param str2: 指定字符串2 :return: None """ str3 = '' for i in str1 + str2: if i.isupper(): str3 += i print(str3) upper1('ohAofIHAOFH45646', 'ASDF545adsa') # 练习3:定义一个函数,删除列表中所有的空值(包括None,和其他空值(比如空字符串、空列表、空元组等)) # 条件对应的表达式如果不是布尔,就转换成布尔看结果是否为True(0和空值是False) def del_none(list1): """ 删除列表中所有的空值 :param list1: 指定列表 :return: None """ list2 = [] for i in list1: if i or i == 0: list2.append(i) print(list2) del_none(['', [], None, 1, 'abc', (), 0]) 输出: 4 AIHAOFHASDF [1, 'abc']
调用函数
-
调用函数(使用函数 - 使用机器)
语法:
函数名(实参列表)
说明:
1)函数名 - 需要那个函数对应的功能,就调用那个函数就写那个函数的函数名
注意:函数名必须是已经定义过的函数的函数名
2)() - 固定写法
3)实参列表 - 以’数据1,数据2,数据3,…'的形式存在, 这儿的每个数据就是一个实参。(实参对应的数据可以是任何有结果的表达式)
实参是用来给形参赋值的,在提供实参的时候要保证和形参一一对应
变量名1,变量名2,变量名3,… = 数据1,数据2,数据3,… —> 实参 = 形参
重要结论:定义函数不会执行函数体,调用函数的时候才会执行函数体 -
函数调用过程
每次在调用函数的时候,它的执行步骤:
第一步:回到函数定义的位置
第二步:传参(用实参给形参赋值,传参的时候必须保证每个形参都有值)
第三步:执行函数体
第四步:确定函数返回值
第五步:回到函数调用的位置,接着往后执行def func4(x, y, z): # x=100,y=200,z=300 print(f'x:{x},y:{y},z:{z}') func4(100, 200, 300) print('end!')
-
关于形参几种错误的写法
# 示例;定义一个函数统计数字字符的个数 # 例如:'asda54' ——> 2 def count_nums(str1): count = 0 for i in str1: if i.isdigit(): count += 1 print(count) # 错误写法1 str1 = 'asda54' def count_nums2(): count = 0 for i in str1: if i.isdigit(): count += 1 print(count) # 错误写法2 def count_nums3(): str1 = 'asda54' count = 0 for i in str1: if i.isdigit(): count += 1 print(count)
函数的参数
-
位置参数和关键字参数
根据实参的提供方式将实参分为位置参数和关键字参数两种
1)位置参数:以’实参1,实参2,实参3,…'的形式存在,让实参和形参从位置上一一对应
2)关键字参数:以’形参1=实参1,形参2=实参2,…‘的形式存在,通过’='将实参和形参对应def func1(x, y, z): print(f'x:{x},y:{y},z:{z}') func1(10, 20, 30) # x:10,y:20,z:30 func1(20, 10, 30) # x:20,y:10,z:30 func1(x=10, y=20, z=30) # x:10,y:20,z:30 func1(y=20, x=10, z=30) # x:10,y:20,z:30 func1(20, y=10, z=30) # x:20,y:10,z:30 func1(20, z=10, y=30) # x:20,y:30,z:10 # func1(x=20, 10, z=30)# 报错! func1(20, 10, z=30) # x:20,y:10,z:30
-
参数默认值
定义函数的时候可以通过’形参名=数据’的方式给形参赋默认值;
在调用函数的时候,有默认值的参数可以不用传参。注意:定义函数的时候如果一个函数有的参数有默认值有的参数没有默认值,没有默认值的形参必须在有默认值的形参前面
def func2(x=10, y=20, z=30): # 不传参 -> x=10,y=20,z=30 print(f'x:{x},y:{y},z:{z}') func2() # x:10,y:20,z:30 func2(100) # x:100,y:20,z:30 func2(100, 200) # x:100,y:200,z:30 func2(100, 200, 300) # x:100,y:200,z:300 # 如果想要跳过前面有默认值的参数,直接给后面的参数赋值,使用关键字参数传参 func2(z=300) # x:10,y:20,z:300 # def func3(x=10, y, z): # 报错!!! # pass
-
参数类型说明
没有默认值参数的类型说明:直接在形参后面加’:类型名’
有默认值的参数,默认值数据对应的类型就是这个形参的类型
def func6(x: str, y=‘’) -> None: 返回值类型说明def func6(x: str, y='') -> None: x.count() y.strip()
-
*对应的不定长参数
1)参数个数不确定可以使用不定长参数
定义函数的时候,如果在某一个形参前加* ,那么这个形参就会变成一个不定长参数,它可以接收多个实参(可以是0,1,2,3…个)
带*的不定长参数的本质是一个元组,它接收到的所有实参是这个元组中的元素。# 示例:定义函数求多个数的和 def sumN(*nums): sum1 = 0 for i in nums: sum1 += i print(sum1) sumN() sumN(10, 20) sumN(1, 2, 3) sumN(1, 2, 3, 4, 5, 6) # 优化,求和的时候至少两个参数 def sumN2(num1, num2, *nums): sum1 = num1 + num2 for i in nums: sum1 += i print(sum1) sumN2(10, 20) sumN2(1, 2, 3) sumN2(1, 2, 3, 4, 5, 6) # 示例:定义一个函数收集学生信息 def get_stu_info(name, age, *awaeds): print(awaeds) get_stu_info('小明', 18) get_stu_info('小明', 18, '三好学生') get_stu_info('小明', 18, '三好学生', '优秀干部')
2)定义函数的时候单独使用*
如果定义函数的时候,形参列表中有一个独立的*,调用函数的时候*后面的所有的形参不需使用关键字参数传参
def func7(x, *, y, z): pass # func7(10, 20, 30) # 报错! func7(10, y=20, z=30) def func8(x, *y, z, t): print(x, y, z, t, sep=',') func8(1, 2, 1, 1, z=4, t=6) # 1,(2, 1, 1),4,6