8.函数
8.1 函数的定义和调用
- 概念:函数就是执行特定任何已完成特定功能的一段代码
- 作用:复用代码、隐藏实现细节、提高可维护性、提高可读性便于调试
- 创建:
def 函数名(参数):
函数体
# 如果有返回值
[return x]
def test(a,b):
c = a+b
return c
result = test(2,3)
print(result)
8.2 函数的参数传递
- 位置传参:根据形参对应的位置进行实参传递
- 关键字实参:根据形参名称进行实参传递
def test(a,b):
c = a+b
return c
# 位置实参 按顺序传递
result1 = test(2,3)
# 关键词参数 按形参的名称进行实参传递 a,b是形参的名称
result2= test(a=2,b=3)
print(result1) #5
print(result2) #5
- 形参和实参变量名可以相同
- 不可变对象,函数体内的修改不会影响实参的值
- 可变对象,函数体内的修改会影响实参的值
def fun(arg1,arg2):
print('arg1:',arg1) #arg1: 3
print('arg2:', arg2) #arg2: [1, 2, 3]
arg1=100
arg2.append(100)
print('arg1:', arg1) #arg1: 100
print('arg2:', arg2) #arg2: [1, 2, 3, 100]
n1 = 3
n2 = [1,2,3]
fun(n1,n2)
print('n1:',n1) #n1: 3 不可变对象,函数体内的修改不会影响实参的值,arg1的修改不影响n1的值
print('n2:',n2) #n2: [1, 2, 3, 100] #可变对象,函数体内的修改会影响实参的值,arg2的改变影响了n2的值
8.3 函数的返回值
- 函数如果没有返回值,return可以不执行
- 函数返回一个值,直接返回类型
- 函数返回多个值时,返回的结果为元组
# !bool(0)的值为False
def fun(num):
odd = [] #奇数
even = [] #偶数
for i in num:
if i%2: #print(bool(0))==False 调转到偶数的增加
odd.append(i)
else:
even.append(i)
return odd,even
list = [1,2,3,2,3,4,5,6]
print(fun(list)) #([1, 3, 3, 5], [2, 2, 4, 6])
8.4 函数的参数定义
- 默认值参数:函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
def fun(a,b=10):
print(a,b)
fun(1) #1 10
fun(1,2) #1 2
- 个数可变的位置参数:定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置形参;使用*定义个数可变的位置形参;结果为一个元组
- 个数可变的关键字参数:定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参;使用**定义个数可变的关键字形参;结果为一个字典
#个数可变的位置参数只能是一个
def fun(*arg):
print(arg)
print(arg[0])
fun(100)
fun(1,2)
#个数可变的关键字参数只能是一个
def fun1(**arg):
print(arg)
fun1(a=1) #{'a': 1}
fun1(a=1,b=2) #{'a': 1, 'b': 2}
#!!在一个函数的定义过程中,如果既有个数可变的位置参数,又有个数可变的关键字参数,个数可变的位置参数要放在前面
def fun2(*arg1,**arg2):
pass
#实参
def fun(a,b,c):
print('a:',a)
print('b:',b)
print('c:',c)
#位置实参
fun(1,2,3)
list = [1,2,3]
#将序列中的每个元素都转换为位置实参 *
fun(*list)
#关键字实参
fun(a=11,c=33,b=22)
dic = {'a':111,'b':222,'c':333}
#将字典中的每个键值对都转换为关键字实参 **
fun(**dic)
'''
a: 1
b: 2
c: 3
a: 1
b: 2
c: 3
a: 11
b: 22
c: 33
a: 111
b: 222
c: 333
'''
#形参
#默认形参
def fun1(a, b, c=1):
print('a:',a)
print('b:',b)
print('c:',c)
#*号以后的变量是关键字形参
def fun2(a,b,*,c):
print('a:', a)
print('b:', b)
print('c:', c)
#个数可变的位置形参
def fun3(*arg1):
print(arg1)
#个数可变的关键字形参
def fun4(**arg2):
print(arg2)
fun1(1,1,2)
'''
a: 1
b: 1
c: 2
'''
fun2(1,2,c=3)
'''
a: 1
b: 2
c: 3
'''
fun3(1,2,3,4,5) #(1, 2, 3, 4, 5)
fun4(a=1,b=2,c=3) #{'a': 1, 'b': 2, 'c': 3}
8.5 函数的作用域
- 含义:程序代码能访问该变量的区域,根据变量的有效范围分为局部变量和全局变量
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明(在函数内声明),这个变量就会就成全局变量
- 全局变量:函数体外定义的变量,可作用于函数内外
8.6 递归函数
- 概念:如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
- 递归的组成部分:递归调用与递归终止条件
- 递归的调用过程:每递归调用一次函数,都会在栈内存分配一个栈帧,每执行完一次函数,都会释放相应的空间
- 递归的优缺点:缺点:占用内存多,效率低下;优点:思路和代码简单
#计算阶乘
def fac(n):
if n==1:
return 1
else:
return n*fac(n-1)
print(fac(6)) #720
#斐波那契数列
def fib(n):
if n==1 or n==2:
return 1
else:
return fib(n-1)+fib(n-2)
#数列上的第六位数字
print(fib(6))
#输出这个数列的前六位上的数字
for i in range(1,7):
print(fib(i),end='t') #1 1 2 3 5 8