一.函数
函数的引入
场景:吃饭
# 吃早饭
print("吃饭")
# 工作
print("工作")
# 吃午饭
print("吃饭")
# 看电影
print("看电影")
# 吃晚饭
print("吃饭")
# 跑步
print("跑步")
1 使用循环简化过程,循环:重复做的事
循环做的事情不能独立分开
循环遇到问题:吃饭之间有其他事情,但是循环一旦执行不能中断,必须全部执行完毕才可以
i = 0
while i<3:
print("吃饭")
i += 1
2 需要函数来解决重复事情中断问题
基本语法格式
定义:函数就是实现特定功能,能够重复使用的代码块(一行或多行)。
# 定义函数的格式
def 函数名([参数1,参数2...]):
"""简要描述函数实现的功能"""
实现功能的代码
[return 返回的数据]
# 调用函数
函数名([参数1,参数2...])
说明:
- def :
define
,用于声明一个函数 - 函数名:标识符,符合标识符的规则和规范。
- []:表示可选内容
- 参数:函数需要外界输入一些依赖的数据,参数可以没有或有一个或多个
- 形参:形式上的参数,在函数定义时参数的名字。
- 实参:实际上的参数,在函数调用时传入的名字。
- return:关键字,用于将函数内的数据返回到函数外。
# 定义一个最基本的函数
def eat():
"""描述吃饭行为"""
print("吃饭")
# 解决引入问题
# 早饭
eat()
# 工作
print("工作")
# wufan
eat()
#
print('看电影')
# 晚饭
eat()
#
print("跑步")
函数的执行流程
3 函数特点
- 函数不调用不执行
- 函数定义只需要一次,调用可以任意次
- 函数必须先定义后调用
4 函数本质
函数名本质和变量本质相同。
a = 10
def eat():
"""描述吃饭行为"""
print("吃饭")
eat()
b = a # 10
c = eat # c就是函数
# 调用函数
c()
二.函数的参数
# 需求定义一个函数,给定一个数字,遍历从1到该数字之间的所有数字
num = int(input("请输入一个整数:"))
def func(n):
"""打印1,n之间的所有数字"""
for i in range(1,n+1):
print(i)
func(num)
# 需求定义一个函数,给定两个数字,遍历两个数字之间的所有数字
def func2(num1,num2):
"""打印num1到num2之间的数字"""
for i in range(num1,num2+1):
print(i)
func2(10,100)
1.位置参数
实参传递的顺序按照形参定义的顺序进行传递的传参方式
# 需求定义一个函数,给定两个数字,遍历两个数字之间的所有数字
def func2(num1,num2):
"""打印num1到num2之间的数字"""
for i in range(num1,num2+1):
print(i)
# 位置参数传递
func2(10,100)
2.关键字参数(函数调用时)
忽略了原本的位置关系,明确指出形参和实参的对应关系:
格式:函数名(形参=实参)
# 需求定义一个函数,给定两个数字,遍历两个数字之间的所有数字
def func2(num1,num2):
"""打印num1到num2之间的数字"""
for i in range(num1,num2+1):
print(i)
# 关键字参数
func2(num1=10,num2=100)
func2(num2=100,num1=10)
3.默认参数(定义函数体现)
在定义函数时,可以对某些形参设定默认值,有默认值的参数,在调用时可以不传入,如果不传入就使用默认值。优先使用传入的值。
使用场景:某个参数变化比较小,就可以指定一个默认值。
学过包含默认值的方法:列表中的pop(index),字符串中的stirp()
# 用户输入个人信息,函数打印个人信息:没有默认值
def print_info(name,age,gender):
"""打印信息"""
print(f"我叫{name},我今年{age}岁,我的性别是{gender}。")
print_info('zs', 20, "男")
print_info('ls', 21, "男")
print_info('ww', 22, "男")
print_info('ml', 19, "男")
# 用户输入个人信息,函数打印个人信息:使用默认值
def print_info(name,age,gender="男"):
"""打印信息"""
print(f"我叫{name},我今年{age}岁,我的性别是{gender}。")
# 不传入包含默认值的参数
print_info('zs', 20,)
print_info('ls', 21,)
print_info('ww', 22,)
print_info('ml', 19,)
4.可变参数(*args,**kwargs)
1 在定义函数时,函数参数很多
2 在定义函数时,不确定函数的数量
-
元组类型可变参数(*args):只能通过位置参数传递
def print_info2(*args): """介绍个人信息""" print(args) for i in args: print(i) # 不善言辞 print_info2() # 正常 print_info2('zs',20,180) print_info2(name='zs', age=20, height = 180) # 错误,不能使用关键字方式传递 # 善谈 print_info2('ls',20,175,70,"郑州","吃") # 定义元组 t = (1,4,5,6,7,8,8,9,9,0,0) print_info2(t) # 传入一个元素:把元组当做一个整体 print_info2(*t) # 传入多个元素:将元组打散
-
字典类型可变参数(**kwargs)
只能通过关键字参数方式传递
def print_info3(**kwargs): """介绍个人信息""" print(kwargs) print_info3('zs',20,180) # 错误 print_info3(name='zs', age=20, height = 180) # 正确
定义万能参数
def func(a, b, c=20, *args, **kwargs):
print(a,b,c) # 1 2 34
print(args) # (4,)
print(kwargs) # {name:zs,age:20}
func(1, 2, 34, 4, name='zs', age=20)
def func2(a, b, *args,c=20, **kwargs):
print(a,b,c) # 1 2 20
print(args) # (34,4)
print(kwargs) # {name:zs,age:20}
func2(1, 2, 34, 4, name='zs', age=20)
总结:
- 在定义函数时:位置参数-- 默认参数和*args–**kwargs
- 在调用函数时:位置参数—关键字参数
三.函数的返回值
-
如果函数需要返回值:
return 内容1,内容2...
-
如果函数有多个返回值,多个值是以元组类型返回的
-
如果没有返回值或是return后无任何数据,那么默认返回None
# 给定一个整数,返回从1到该数字之间所有数的和
# 一个返回值
def func(n):
"""求和"""
s = 0 # 和
for i in range(1,n+1):
s += i
return s
# 多个返回值
def func2():
return 1,1.5,'a',[1,2],(1,2),{1:2},{1,2}
# 没有返回值
def func3():
return
return作用:
- 将函数内的数据返回到函数外
- 用于结束一个函数的执行
def func3():
"""模拟用户登录注册"""
code = input("1:注册,2:登录,3退出")
if code == "1":
pass
elif code == "2":
pass
elif code == "3":
print("退出系统")
return
print("其他代码")
四.函数的相互调用
def f1():
print('f1')
def f2():
print("f2")
f1()
f2()
五.函数的参数
1、传递不可变类型参数,不会影响参数本身
2、传递可变类型参数,如果直接重新赋值,那么也不会影响参数本身,如果直接在原对象基础上进行修改会影响。
案例
def f(n=[]):
n.append(3)
print(f"第二次n的值是{n}")
# 第一次调用
f() # [3]
# 第二次调用使用默认参数:第一次调用会影响第二次
# f() # [3,3]
# 第二次调用不使用默认参数:第一次调用不会影响第二次
f([10]) # [10,3]
六.递归函数
使用递归函数的条件
-
必须留出口
-
自己调用自己
def print_num(num):
if num == 0:
return # 结束函数
print(num)
num -= 1
print_num(num)
print("*************")
print_num(3)
数列:菲波那切数列(兔子数列)
# 1 1 2 3 5 8 13 21 34 55....
# 给定数字n
# 非递归方式
a = 1 # n-2项
b = 1 # n-1项
for i in range(1,n+1):
if i == 1 or i ==2:
print(1)
else:
print(a+b)
a,b = b,a+b
# 递归方式
def fib(n):
"""求第n项的数"""
if n ==1 or n ==2:
return 1
else:
return fib(n-1) +fib(n-2)
print(fib(10))
1 2 3 5 8 13 21 34 55…
给定数字n
非递归方式
a = 1 # n-2项
b = 1 # n-1项
for i in range(1,n+1):
if i == 1 or i ==2:
print(1)
else:
print(a+b)
a,b = b,a+b
递归方式
def fib(n):
"""求第n项的数"""
if n ==1 or n ==2:
return 1
else:
return fib(n-1) +fib(n-2)
print(fib(10))