一、函数的作用
没有函数会遇到什么问题:
a. 相同功能对应的代码需要重复写
b. 一旦功能发生改变,需要将使用到这个功能的代码的位置全部修改
针对上述问题,使用函数举例:
左->右->左3->右2->左2->右3
def left():
print('===============左移==============')
print('向左打方向灯')
print('向左打方向盘')
# print('踩油门')
print('回正方向盘')
def right():
print('===============右移==============')
print('向右打方向灯')
print('向右打方向盘')
print('踩油门')
print('回正方向盘')
left()
right()
left()
left()
left()
right()
right()
left()
left()
right()
right()
right()
二、函数基础
1.认识函数
a.什么是函数
函数就是对实现某一特定功能的代码的封装。(机器)
b.函数的分类(谁定义的函数)
系统函数:python已经定义好,程序员可以直接使用的函数。例如:print、input、type、chr、ord、id、max、min、sum、sored等(别人已经造好的机器)
自定义函数:由程序员自己定义,程序员可以自己使用或者给别人使用的函数。(自己造机器)
2.定义函数(造机器)
“”"
语法:
def 函数名(形参列表):
函数说明文档
函数体
说明:
- def - 关键字;固定写法
- 函数名 - 程序员自己命名;
要求:标识符、不能是关键字
规范:字母小写,单词之间用_隔开;
见名知义(看到函数名大概知道函数的功能);
不使用系统的函数名、类型名和模块名 - (): - 固定写法(不能省略)
- 形参列表 - 以 ‘变量名1,变量名2,变量名3,…’ 的形式存;
形参的作用是将函数外部的数据传递到函数里面(如果实现函数的功能需要提供外部数据,那么这个函数就需要形参) - 函数说明文档 - 函数的说明书;本质就是用""""""引起来的注释
- 函数体 - 和def保持一个缩进的一条或者多条语句(至少一条);
实现函数功能的代码段
(重点)注意:定义函数的时候不会执行函数体
def func1():
print('=========')
list1 = [1, 2]
print(list1[10])
示例1:定义一个函数求任意两个数字的和
def sum1(num1, num2):
"""
求两个数字的和 - (函数功能说明区)
:param num1: 提供第一个数字 - (参数说明)
:param num2: 提供第二个数字 - (参数说明)
:return: None - (返回值说明)
"""
print(num1+num2)
练习1:定义一个函数,求一个数的阶乘:N! = 1234…*N
def factorial(num):
"""
求一个数的阶乘
:param num: 指定的数字
:return: None
"""
s = 1
for x in range(1, num+1):
s *= x
print(f'{num}的阶乘是:{s}')
练习2:写一个函数将两个字符串交叉合并
# 'abc'、'123' -> a1b2c3
# 'abc'、'12345' -> a1b2c345
# 'abcdef'、'1234' -> a1b2c3d4ef
def merge(str1, str2):
len1 = len(str1)
len2 = len(str2)
# 先交叉拼接相同长度的部分
new_str = ''
for index in range(min(len1, len2)):
new_str += str1[index] + str2[index]
# 再确定尾部
if len1 > len2:
new_str += str1[len2:]
else:
new_str += str2[len1:]
print(new_str)
# merge('abc', '123567')
3.调用函数(使用机器)
语法:
函数名(实参列表)
说明:
函数名 - 需要使用的已经定义好的函数的函数名
() - 固定写法
实参列表 - 以 ‘数据1,数据2,数据3,…’ 的形式存在;
实参就是需要从函数外部传递到函数内容使用的具体的数据(默认情况下被调用的函数有多少形参就需要提供多少个实参)
sum1(90, 10)
# 同一个函数可以条用多次
sum1(11.1, 22.2)
factorial(5) # 5的阶乘是:120
factorial(10) # 10的阶乘是:3628800
三、函数的参数
1.位置参数和关键字参数
根据实参的传递方式将实参分为位置参数和关键字参数两种
1)位置参数
以 ‘实参1,实参2,实参3,…’ 形式存在,让实参和形参一一对应
2)关键字参数
以 '形参1=实参1,形参2=实参2,…'形式存在,这个参数的位置可以随意更改
3)位置参数和关键字参数混用
位置参数必须在关键字参数的前面
def func1(a, b, c):
print(f'a:{a}, b:{b}, c:{c}')
位置参数
func1(10, 20, 30) # a:10, b:20, c:30
func1(30, 20, 10) # a:30, b:20, c:10
关键字参数
func1(a=100, b=200, c=300) # a:100, b:200, c:300
func1(b=200, c=300, a=100) # a:100, b:200, c:300
混用
func1(10, 20, c=30) # a:10, b:20, c:30
func1(100, c=230, b=220) # a:100, b:220, c:230
# func1(500, 600, a=400)
# func1(a=400, 500, 600)
2.参数默认值
定义函数的时候可以直接给一个或者多个形参赋默认值;有默认值的参数在调用的时候可以不传参。
def func2(a=1, b=2, c=3):
print(f'a:{a}, b:{b}, c:{c}')
func2() # a:1, b:2, c:3
func2(10, 20) # a:10, b:20, c:3
func2(b=200) # a:1, b:200, c:3
def func3(a, b, c=3):
print(f'a:{a}, b:{b}, c:{c}')
func3(100, 200) # a:100, b:200, c:3
func3(100, 200, 300) # a:100, b:200, c:300
有默认值的参数必须在没有默认值参数的后面
def func4(a, c, b=200):
print(f'a:{a}, b:{b}, c:{c}')
func4(1, 3) # a:1, b:200, c:3
3.不定长参数
定义函数的时候如果参数个数不确定,可以使用不定长参数
1)带的不定长参数
在形参前加让这个形参变成不定长参数,可以同时接受多个实参。这个参数的本质就是一个元组,传递的对应的实参全部会变成这个元组中的元素。(必须使用位置参数传参)
2)带的不定长参数
在形参前加让这个形参变成不定长参数,可以同时接受多个实参。这个参数的本质就是一个字典(必须使用关键字参数传参,关键字自己随意命名)
“”"
定义一个函数,求多个数的平均值
def mean(*num):
if len(num) == 0:
print('0')
else:
print(sum(num)/len(num))
mean()
mean(10)
mean(20, 12)
mean(20, 12, 23, 23, 432, 121, 90)
def func5(*a):
print('a:', a)
func5(23, 45)
func5(1, 2, 3, 4)
这儿的x必须使用位置参数传参
def func6(x, *a):
print('a:', a, 'x:', x)
func6(20) # a: () x: 20
func6(10, 20, 30, 40) # a: (20, 30, 40) x: 10
这儿的x必须使用关键字参数传参
def func7(*a, x=90):
print('a:', a, 'x:', x)
func7(23, 34, 45) # a: (23, 34, 45) x: 90
func7(1, 2, 3, 4, x=100) # a: (1, 2, 3, 4) x: 100
def func8(**num):
print(num)
func8()
func8(a=100) # {'a': 100}
func8(name='张三', age=30) # {'name': '张三', 'age': 30}
面试题:func(args, **kwargs) , 函数func中args, **kwargs有什么意义
让函数调用的时候更加灵活
def func(*args, **kwargs):
pass
func()
func(2, 3, 4)
func(a=23, b=23, c=34, d=11)
func(23, 31, a=1, b=290)