一、认识函数
1)什么是函数
函数就是实现某一特定功能的代码的封装,是将实现某一功能的代码打一个包,以后在使用这段代码对应的功能时不用再重新写这段代码,而是直接使用这个函数就行了。
2)函数的分类
根据这个函数时由谁创建的,将函数分为系统函数和自定义函数两种:
1)系统函数 - 由系统创建的函数(Python本身就创建好的函数)例如:print、input、type、max、min等。
2)自定义函数 - 由程序员自己创建的函数。
3)定义函数
'''
语法:
def 函数名(形参列表):
函数说明文档
函数体
'''
-
def: 关键字,固定写法
-
函数名:
1)由程序员自己命名
2)两个要求:是标识符;不是关键字
3)三个规范:
- 见名知义(看到函数名就大概知道函数的功能是什么);
- 所有的字母都小写,多个单词用下划线隔开;
- 不使用系统的函数名
-
(): - 固定写法
-
形参列表
以’变量名1,变量名2,变量名3,……'的形式存在,根据情况变量的数据可以为0(每一个变量就是一个形参)。
形参的作用:将函数外部的数据传递到函数里面。
确定形参的方法:看实现函数的功能需不需要额外的数据,需要多少个额外的数据。
-
**函数说明文档 **
多行注释(相当于说明书)
-
函数体
结构上,和def保持一个缩进的一条或者多条语句
逻辑上,函数体就是实现函数功能的代码
示例:
求一个字符串中数字的个数:
def str1(strN):
count = 0
for i in strN:
if '0' <= i <= '9':
count += 1
print(count)
str1('ashdg123') # 3
将两个字符串中的大写字母提取到一个新字符串中打印出来:
def str2(strM, strJ):
str_new = strM + strJ
strn = ''
for i in str_new:
if i.isupper():
strn += i
print(strn)
str2('ashJg123', 'FHGkjhsa') # JFHG
将一个列表中所有的None值(包括空列表,空元组,空字典等等)删除
def list1(num1):
'''
:param num1: 指定字符串
:return: None
'''
for i in num1[:]:
# 条件对应的表达式如果不是布尔,就转换成布尔值,如果结果是True就执行(0值和空值是False,其他的都是True)
if not i and i != 0:
num1.remove(i)
print(num1)
list1([2,[],{},1,None])
二、调用函数
"""
语法:
函数名(实参列表)
"""
-
函数名
需要哪个函数对应的功能,就调用哪个函数;想要调用哪个函数就写哪个函数的函数名。
注意:函数名必须是已经定义过的函数的函数名
-
() - 固定写法
-
实参列表
以’数据1, 数据2, 数据3,…'的形式存在,这儿的每个数据就是一个实参。
实参对应的数据可以是任何有结果的表达式
实参是用来给形参赋值,在提供实参的时候要保证和形参一一对应。
变量名1,变量名2,变量名3,… = 数据1, 数据2, 数据3,… —> 形参 = 实参
重要结论:定义函数不会执行函数体,调用函数的时候才会执行函数体
示例:
def func2(x, y):
pass
a = 20
func2(10, a)
func2(a * 2, 10 > 20)
1)函数调用过程
调用函数执行步骤:
- 回到函数定义的位置
- 传参(用实参给形参赋值, 传参的时候必须保证每个形参都有值)
- 执行函数体
- 确定函数返回值
- 回到函数调用的位置,接着往后执行
def func3(x, y, z): # x=100, y=200, z=300
print(f'x:{x}, y:{y}, z:{z}')
func3(100, 200, 300)
三、函数的参数
-
位置参数
以’实参1,实参2,实参3,…'的形式存在,让实参和形参从位置上一一对应。
-
关键字参数
以’形参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(10, y=20, z=30) # x:10, y:20, z:30
func1(10, z=30, y=20) # x:10, y:20, z:30
# func1(x=10, 20, z=30) # 报错!
func1(10, 20, z=30) # x:10, y:20, z:30
1)参数默认值
定义函数的时候可以通过’形参名=数据’的方式给形参赋默认值
在调用函数的时候,有默认值的参数可以不用传参
如果想要跳过前面有默认值的参数,直接给后面的参数赋值,使用关键字参数传参
定义函数的时候,如果一个函数有的参数有默认值有的参数没有默认值,没有默认值的形参必须在有默认值的形参的前面。
示例:
def func2(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
2)参数类型说明
(1)没有默认值参数的类型说明:直接在形参后面加’:类型名’;
(2)有默认值的参数,默认值数据对应的类型就是这个形参的类型
3) * 对应的不定长参数
在参数个数不确定可以使用不定长参数。
定义函数的时候,如果在某一个形参前面加,那么这个形参就会变成一个不定长参数,它可以接收多个实参(可以是0个、1个、2个、…、10个…)*
带*的不定长参数的本质是一个元组,它接收到的所有的实参是这个元组中的元素。
示例:
定义函数求多个数的和
def sumN(*nums):
sum1 = 0
for x in nums:
sum1 += x
print(sum1)
sumN() # 0
sumN(10) # 10
sumN(10, 20) # 30
sumN(1, 23, 45) # 69
sumN(89, 23, 7, 12, 10) #141
进行优化:
def sumN2(num1, num2, *nums):
sum1 = num1 + num2
for x in nums:
sum1 += x
print(sum1)
sumN2(10, 20) # 30
sumN2(10, 20, 30, 40, 50) # 150
4)定义函数的时候单独使用*
如果定义函数的时候,形参列表中有一个独立的 * 调用函数的时候后面的所有的形参必须使用关键字参数传参。
案例:
def func9(x, *y, z, t):
print(x) # 10
print(y) # (27, 89, 34, 78, 34)
print(z, t) # 100,200
func9(10, 27, 89, 34, 78, 34, z=100, t=200)