函数
函数存在的价值:
当一个功能需要反复使用的时候,如果没有函数,每次需要这个功能就必须把实现这个功能的代码写一遍。如果有函数, 实现功能对应的代码只需要写一遍(封装成函数),然后再每次需要这个功能的时候调用实现这个功能的函数。
def sumN(num):
sum1 = 0
for x in range(1, num+1):
sum1 += x
print('和:', sum1)
# 1 + 2 + 3 + ... + 100
sum1 = 0
for x in range(1, 101):
sum1 += x
print('和:', sum1)
sumN(100)
# 1 + 2 + 3 + ... + 50
sum1 = 0
for x in range(1, 51):
sum1 += x
print('和:', sum1)
sumN(50)
1 + 2 + 3 + ... + 1000
sum1 = 0
for x in range(1, 1001):
sum1 += x
print('和:', sum1)
sumN(1000)
def get_nums(str1):
new_str1 = ''
for x in str1:
if x.isdigit():
new_str1 += x
print(new_str1)
#提取'shhk237水电费9292KJs8'
str1 = 'shhk237水电费9292KJs8'
new_str1 = ''
for x in str1:
if x.isdigit():
new_str1 += x
print(new_str1)
get_nums('shhk237水电费9292KJs8')
#提取电话号码:'电话号码是:162382387738,有事情找我'
str1 = '电话号码是:162382387738,有事情找我'
new_str1 = ''
for x in str1:
if x.isdigit():
new_str1 += x
print(new_str1)
get_nums('电话号码是:162382387738,有事情找我')
#提取薪资
'我是一个工人,每月工资8000块'
str1 = '我是一个工人,每月工资8000块'
new_str1 = ''
for x in str1:
if x.isdigit():
new_str1 += x
print(new_str1)
get_nums('我是一个工人,每月工资8000块')
1.什么是函数(机器)
函数就是实现某一特定功能的代码的封装。
(函数就将实现某一个或者某类功能的代码打成一个包,以后在需要这包中的这段代码对应的功能的时候不用重新写这段代码,而是使用封装了这段代码的函数)
函数的分类
根据这个函数是由谁创建的,我们将函数分为系统函数和自定义函数两种
- 系统函数(别人已经造好的机器) - 由系统创建的函数(Python本身就创建好的函数),例如:print、input、type、max、min等
- 自定义函数(自己造的机器) - 由程序员自己创建的函数
- 定义函数(造机器)
“”"
语法:
def 函数名(形参列表):
函数说明文档
函数体
说明:
1)def - 关键字;固定写法
2)函数名 - 由程序员自己命名;
两个要求:是标识符;不是关键字
三个规范:见名知义(看到函数名就大概知道函数的功能是什么);
所有的字母都小写,多个单词用下划线隔开;
不使用系统的函数名、类名和模块。
3)(): - 固定写法
4)形参列表 - 以’变量名1,变量名2,变量名3,…'的形式存在,根据情况变量的数据可以为0(每一个变量就是一个形参)。
形参的作用:将函数外部的数据传递到函数里面。
确定形参的方法:看实现函数的功能需不需要额外的数据,需要多少个额外的数据。
5)函数说明文档 - 就是多行注释(相当于生活中机器的说明书)
6)函数体 - 结构上,和def保持一个缩进的一条或者多条语句
逻辑上,函数体就是实现函数功能的代码。
“”"
#定义一个函数求一个数的阶乘
def factorial(num):
"""
(功能说明区)求一个数的阶乘:num!
:param num: (参数说明)求阶乘的对象
:return:(返回值说明)None
"""
sum1 = 1
for x in range(1, num+1):
sum1 *= x
print(sum1)
factorial(10)
factorial(5)
定义一个函数求两个数的乘积
def product(num1, num2):
print(num1 * num2)
练习:定义一个函数统计字符串中数字字符的个数
def count_nums(str1):
"""
统计str1对应的字符串中数字字符的个数
:param str1: 指定的字符
:return: None
"""
count = 0
for x in str1:
if x.isdigit():
count += 1
print(count)
练习2:定义一个函数,将两个字符串中所有的大写字母合并成一个新的字符串
def merge_upper(str1, str2):
new_str = ''
for x in str1 + str2:
if x.isupper():
new_str += x
print(new_str)
merge_upper('mnHK', 'shsJKO是LM12')
练习3:定义一个函数,删除列表中所有的空值(包括None,和其他空值(比如空字符串、空列表、空元组等))
def remove_null_value(list1):
for x in list1[:]:
if (not x) and (x != 0):
list1.remove(x)
print(list1)
remove_null_value([10, 20, 'abc', '', {}, 100, (), 0])
#条件对应的表达式如果不是布尔,就转换成布尔看结果是否为True (0值和空值是False, 其他都是True)
调用函数(使用函数 - 使用机器)
语法:
函数名(实参列表)
说明:
1)函数名 - 需要哪个函数对应的功能,就调用哪个函数;想要调用哪个函数就写哪个函数的函数名。
注意:函数名必须是已经定义过的函数的函数名
2)() - 固定写法
3)实参列表 - 以’数据1, 数据2, 数据3,…'的形式存在,这儿的每个数据就是一个实参。(实参对应的数据可以是任何有结果的表达式)
实参是用来给形参赋值,在提供实参的时候要保证和形参一一对应。
变量名1,变量名2,变量名3,... = 数据1, 数据2, 数据3,... ---> 形参 = 实参
重要结论:定义函数不会执行函数体,调用函数的时候才会执行函数体
def func1():
pass
func1()
def func2(x, y):
pass
a = 20
func2(10, a)
func2(a * 2, 10 > 20)
def func3():
print('======')
print('++++++')
print('------')
func3()
func3()
- 函数调用过程
“”"
每次在调用函数的时候,它的执行步骤:
第一步:回到函数定义的位置
第二步:传参(用实参给形参赋值, 传参的时候必须保证每个形参都有值)
第三步:执行函数体
第四步:确定函数返回值
第五步:回到函数调用的位置,接着往后执行
“”"
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!')
- 关于形参几种错误的写法
示例:定义一个函数统计数字字符的个数
例如:'man闪烁234' -> 3
def count_nums(str1):
count = 0
for x in str1:
if x.isdigit():
count += 1
print(count)
```
## 位置参数和关键字参数
根据实参的提供方式将实参分为位置参数和关键字参数两种
"""
1)**位置参数**:以'实参1,实参2,实参3,..'的形式存在,让实参和形参从位置上一一对应
2)**关键字参数**:以'形参1=实参1, 形参2=实参2,...'的形式存在,通过'='将实参和形参对应
注意:位置参数和关键字参数可以一起用,但是必须保证位置参数在关键字参数的前面
"""
```python
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)
func1(10, z=30, y=20)
func1(x=10, 20, z=30) # 报错!
func1(10, 20, z=30)
2.参数默认值
“”"
定义函数的时候可以通过’形参名=数据’的方式给形参赋默认值;
在调用函数的时候,有默认值的参数可以不用传参。
注意:定义函数的时候,如果一个函数有的参数有默认值有的参数没有默认值,没有默认值的形参必须在有默认值的形参的前面
“”"
def func2(x=10, y=20, z=30):
print(f'x:{x}, y:{y}, z:{z}')
func2()
func2(100)
func2(100, 200)
func2(100, 200, 300)
如果想要跳过前面有默认值的参数,直接给后面的参数赋值,使用关键字参数传参
func2(z=300)
def func3(x, y=20, z=30):
pass
def func4(x, y, z=30):
pass
def func5(x=10, y, z): # 报错!
pass
3.参数类型说明
没有默认值参数的类型说明:直接在形参后面加’:类型名’;
有默认值的参数,默认值数据对应的类型就是这个形参的类型
def func6(x: str, y='') -> str:
return x.strip()
print()
*4.对应的不定长参数
1)参数个数不确定可以使用不确长参数
定义函数的时候,如果在某一个形参前面加*,那么这个形参就会变成一个不定长参数,它可以接收多个实参(可以是0个、1个、2个、…、10个…)
带 * 的不定长参数的本质是一个元组,它接收到的所有的实参是这个元组中的元素。
# 示例:定义函数求多个数的和
def sumN(*nums):
sum1 = 0
for x in nums:
sum1 += x
print(sum1)
sumN()
sumN(10)
sumN(10, 20)
sumN(1, 23, 45)
sumN(89, 23, 7, 12, 10)
# 优化,求和的时候至少两个参数
def sumN2(num1, num2, *nums):
sum1 = num1 + num2
for x in nums:
sum1 += x
print(sum1)
sumN2(10, 20)
sumN2(10, 20, 30, 40, 50)
# 示例:定义一个函数收集学生信息
def get_stu_info(name, age, *awards):
print(awards)
get_stu_info('小明', 18)
get_stu_info('小明', 18, '三好学生')
get_stu_info('小明', 18, '三好学生', '优秀干部')
- 定义函数的时候单独使用*
“”"
如果定义函数的时候,形参列表中有一个独立的*,调用函数的时候*后面的所有的形参必须使用关键字参数传参
“”"
def func7(x, *, y, z):
pass
func7(10, y=20, z=30)
def func8(*, a, b):
pass
def func9(x, *y, z, t):
print(x)
print(y)
print(z, t)
func9(10, 27, 89, 34, 78, 34, z=100, t=200)