函数基础
1. 函数基础
函数的价值:
1)将代码块分块 2)将重复性功能进行封装以简化程序
1. 认识函数
1)概念:函数就是对实现某一特定功能的代码的封装 - 机器 函数的本质就是一段代码(包在函数内的那些代码)
2)函数的分类 系统函数(系统造好的机器) - 由python创建好的函数,例如:print、input、type、max、min、id等
自定义函数 - 由程序员自己创建的函数
2.定义函数(创建函数)
语法:
def 函数名(形参列表):
函数说明文档
函数体
说明:
a. def - 关键字:固定写法
b. 函数名 - 由程序员自己命名
? 要求:是标识符;不能是关键字
? 规范:见名知义(看到函数名大概知道该函数的功能是什么);
? 所有字母都小写,多个单词之间用下划线隔开;
? 不使用系统的函数名、类名和模块名。
c. () - 固定写法
d. 形参列表 - 以’变量名1, 变量名2, 变量名3, …'格式存在。
? 这儿的每一个变量就是一个形参,如果不需要形参,括号里什么都不写,但括号必须写
? 形参是用来将函数外部的数据传递到函数内部。(可以理解成连接函数外部和内部的通道(只进不出))
? 是否需要形参:看实现函数的功能需不需要额外的数据
e. : - 固定写法
f. 函数说明文档 - 本质就是文档注释
? 相当于机器的说明书;
? 可有可无
g. 函数体 - 和def保持一个缩进的一条或多条语句;
? 函数体就是实现函数功能的代码
def sum2(num1, num2):
'''获得两个数的和'''
print(num1 + num2)
def factorical(n):
'''求取一个数的阶乘'''
result = 1
for x in range(1, n + 1):
result *= x
print(result)
3. 定义函数的基本流程
初学者定义函数的基本流程:
第一步:确定函数功能
第二步:根据函数功能确定函数名
第三步:确定形参(看实现函数的功能需不需要额外的数据,需要几个)
第四步:实现函数功能(将形参当成对应的数据来使用)
第五步:确定函数返回值
第六步:写函数说明文档
2. 调用函数
调用函数(使用机器)
- 定义函数的时候不会执行函数体,调用函数的时候才会执行函数体(重要!)
? 即使函数体内的代码有错也不会报错
-
调用函数 语法:
函数名(实参列表)
说明:
a. 函数名 - 需要使用的函数的名字。(函数名必须是已经定义过的函数的函数名) b. () - 固定写法 c. 实参列表 - 多个数据用逗号隔开:数据1,数据2,数据3,… 原则上定义函数的时候有多少个形参,调用函数需要多少个实参
-
函数调用过程 当代码执行到函数调用表达式的时候: 第一步:回到函数定义的位置,用实参给形参赋值(传参) 第二步:执行函数体 第三步:确定函数返回值 第四部:回到函数调用的位置,接着往后执行
def func1():
print('=======')
func1()
func1()
def func1():
pass
def func2(x):
pass
def func3(x):
pass
func3(200 - 100)
str1 = 'abc'
func3(str1[1])
func3(str1.upper())
func3(str1.upper() + '123')
3. 返回值
返回值 - 将函数内部的数据传递到函数外部
打印 - 只是程序调试的手段,并不是返回值
-
怎样将一个数据作为函数的返回值 语法: return 需要返回的数据(需要从函数内部传递到函数外部的数据);多个数据之间用逗号隔开 注意:若函数体内未写return,仍然有返回值,返回值为None -
怎样在函数外部获取函数的返回值 获取函数调用表达式的值就是获取函数的返回值。(函数调用表达式的值就是函数的返回值) 返回值能做的事,函数调用表达式都可以做
def my_sum(num1, num2):
return num1 + num2
sum1 = my_sum(10, 20)
print(sum1)
print(my_sum(10,20))
def func(x, y):
x.append(y*2)
return x
list1 = [func([10, 20], 30), 'abc']
print(list1[0][-1])
4. return关键字
return的作用有两个:
- 确定函数返回值(将函数内部的数据传递到函数外部)
- 提前结束函数(在执行函数体的时候,如果遇到了return,那么函数直接结束)
def func1():
print('----')
return 10
print('++++')
print('====')
func1()
print(func1())
def download(state):
if not state:
return
print('连接服务器,下载数据')
download(True)
download(False)
def odevity(num):
if num % 2:
return '奇数'
return '偶数'
5. 函数参数
5.1 位置参数和关键字参数
- 位置参数 - 直接将多个数据用逗号隔开,让实参和形参从位置上一一对应(第一个实参给第一形参赋值,第二个实参给第二个形参赋值)
- 关键字参数 - 以’形参’='实参’的形式传参
- 位置参数和关键字参数混用 - 位置参数必须在关键字参数前面
def func1(x, y, z):
print(f'x:{x},y:{y},z:{z}')
func1(10, 20, 30)
func1(x=10, y=20, z=30)
func1(x=10, z=30, y=20)
func1(10, 20, z=30)
func1(10, z=30, y=20)
result = sorted([23, 46, 53, 32], reverse=True)
5.2 参数默认值
定义函数的时候可以通过’形参 = 数据’给参数赋默认值,调用函数的时候有默认值的参数可以不用传参。
定义函数的时候可以只给部分参数赋默认值,那么这个时候没有默认值的参数必须在有默认值参数的前面。
def func2(x, y=20, z=30):
print(f'x:{x},y:{y},z:{z}')
func2(10)
func2(100)
func2(100, 200)
func2(10, y=200)
5.3 参数类型说明和返回值类型说明
参数类型说明:
-
无默认值参数:类型名 -
参数赋默认值(默认值的类型就是参数的类型) 有参数类型说明的好处:写代码时有对应数据类型的代码提示 -
返回值类型说明:-> 类型名
def func4(x: list, y=''):
pass
def func5(x: list, y='') -> list:
pass
5.4 不定长参数
不定长参数 - 一个形参可以同时接受多个实参(包括0个)
-
在参数名前加 * ,那么这个参数就可以同时接受多个实参(必须是位置参数)。 原理:带 * 的参数会变成一个元组,接受到的实参会变成元组中的元素。(如果参数是0个,则带 * 的参数就是一个空元组) 带 * 的参数的前面和后面还能有定长参数 注意:带*的不定长参数在传参的时候只能用位置参数 (掌握!)重要结论:定义函数的时候,如果参数中有一个独立的*(*后无参数),*的作用是让在调用函数的时候*后面的参数必须用关键字参数传参。 -
在参数名前加 ** ,那么这个参数就可以同时接受多个实参(必须是关键字参数)。 原理:带**的参数会变成一个字典,接受到的实参会变成字典中的键值对。 带**的参数传参时,参数名可以任取。
def sum1(*x):
pass
print(f'x:{x}')
sum1()
sum1(20)
sum1(10, 20)
sum1(10, 20, 34, 5, 6)
def func5(x, y, *z):
print(f'x:{x}, y:{y}, z:{z}')
func5(10, 20)
func5(10, 20, 30, 40)
def func5(x, *y):
print(f'x:{x},y:{y}')
func5(10, 20, 30)
def func6(*x, y):
print(f'x:{x},y:{y}')
func6(10, 20, y=30)
def func8(x, *, y, z):
pass
func8(10, y=20, z=30)
def func9(**x):
pass
func9()
func9(a=10, b=20, c=30)
|