函数
函数
函数:执行特定任务和以完成特定功能的一段代码。
为什么需要函数:复用代码、隐藏实现细节、提高可维护性、提高可读性便于调试;
函数创建以及调用
函数创建格式:
def 函数名(输入参数【注解:形参】):
函数体
[return xxx] # 可以忽略
函数的调用:
函数名(输入参数【注解:实参】)
## 函数创建
def addNum(a,b):
return a+b
#函数调用
num1 = addNum(1,3)
print(num1) # 4
## 函数创建无参数,无返回值return
def printHello():
print('Hello world')
函数的参数传递
位置实参
位置实参:根据形参对应的位置进行实参传递。
def calc(a,b,c):
return a+b+c
# 位置实参-把1传给a,把2传给b,把3传给c
print(calc(1,2,3)) # 6
关键字实参
关键字实参:根据形参的名称进行实参传递。
def calc(a,b,c):
return a+b+c
# 关键字实参传递,通过形参名进行传递,可以不按顺序传递值,位置传参时不可不按顺序传递值;
print(calc(a=1,b=3,c=6)) # 10
print(calc(a=1,c=3,b=2)) # 6
注意事项
在函数调用过程中进行参数的传递。如果不可变对象,在函数体的修改不会影响实参的值;如果是可变对象,在函数体的修改会影响实参的值。
## 传入参数为不可变对象,比如字符串、数字、元组等
def modValue(a):
a = '12345'
print('函数内的值:', a)
str1 = 'aaa'
modValue(str1)
print(str1) # aaa
bool1 = True
modValue(bool1)
print(bool1) # True
## 传入参数为可变对象,比如列表、集合、字典
def modVlaue1(a):
a[1] = 123
print("xxxx", a)
list1 = [1,2,3,4]
modVlaue1(list1)
print(list1) # [1, 123, 3, 4]
# 传入参数为可变对象,修改可变对象中的值,会影响实际传参的值;
def modVlaue1(a):
a = 123
print("xxxx", a)
list1 = [1,2,3,4]
modVlaue1(list1)
print(list1) # [1, 2, 3, 4]
# 传入参数为可变对象,修改可变对象的值,不会影响实际传参的值
函数的返回值
如果函数没有返回值,return可以省略不写,函数调用时返回None
def printHello(name):
print('Hello, ',name)
print(printHello('HongHong')) # None
如果函数的返回值1个,直接返回单独一个值。
def calc(a, b):
return a + b
print(calc(10,20)) # 30
如果函数的返回值多个,返回的结果为元组
def printList(a, b):
return a, b, a+b
print(printList(5,9)) # (5, 9, 14)
函数的参数定义
函数定义默认值参数
函数定义默认值参数:函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参。例子def fun(a,b=10)
def fun(a, b=10):
return a + b
#只传递a,不传递b
print(fun(5)) # 15
#分别传递a,b值
print(fun(5,5)) # 10
个数可变的位置参数
个数可变的位置参数:定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数。def fun(*args)
def fun(a, b, *args):
print("a = ",a)
print("b = ",b)
print(args)
fun(1,2,3,4,5,6)
##输出结果
# a = 1
# b = 2
# (3, 4, 5, 6)
个数可变的关键字形参
个数可变的关键字形参:定义函数时,可能无法事先确定传递的关键字实例的个数时,使用可变的关键字形参。def fun(**kargs)
def fun(a,b, *args, **kargs):
print("a = ",a)
print("b = ",b)
print(args)
print(kargs)
fun(1,2,3,4,5, c=1,x=23,y='abc')
#输出结果:
# a = 1
# b = 2
# (3, 4, 5)
# {'c': 1, 'x': 23, 'y': 'abc'}
注意事项
在一个函数的定义过程中,既有个数可变的关键字参数,也有个数可变的位置参数。要求个数可变的位置参数要放在个数可变的关键字参数之前。
def fun(a,b, *args, **kargs):
print("a = ",a)
print("b = ",b)
print(args)
print(kargs)
fun(1,2,3,4,5, c=1,x=23,y='abc')
#输出结果:
# a = 1
# b = 2
# (3, 4, 5)
# {'c': 1, 'x': 23, 'y': 'abc'}
def fun(a,b, **kargs, *args): # SyntaxError: invalid syntax
print("a = ",a)
print("b = ",b)
print(args)
print(kargs)
例子1:使用不同的传参方式传参
一个函数,需要传递a,b,c,d四个参数,使用不同的传参方式传参。
# 全部位置传参
fun(1,2,3,4) # 1 2 3 4
# 全部关键子传参
fun(a=1,b=2,d=4,c=3) # 1 2 3 4
# 位置传参和关键子传参组合
fun(1,2,c=12,d=15) # 1 2 12 15
例子2:要求cd只能采用关键字实参传递
函数需要传递a,b,c,d四个参数,要求cd只能采用关键字实参传递。
def fun(a,b,*,c,d):
print(a,b,c,d)
fun(1,2,c=11,d=12) # 1 2 11 12
# fun(1,2,3,4) # TypeError: fun() takes 2 positional arguments but 4 were given
# 上面调用,把3和4这个值传给了函数中的*这个变量,所以你这边相当于只传入了2个参数a,b
fun(a=1,b=2,c=3,d=4) # 1 2 3 4
解包和打包
解包
def fun(a,b,c,d):
print(a,b,c,d)
list1 = [1,2,3,4]
fun(*list1) # 1 2 3 4
#上面的过程就是解包的过程,把列表的值取出来分别赋给a,b,c,d
dict1={'a':23,'c':55,'d':100,'b':33}
fun(**dict1) # 23 33 55 100
#上面的过程就是解包的过程,把字典的值按照key的对象关系传递给函数。
打包
def fun(a,b, *args, **kargs):
print("a = ",a)
print("b = ",b)
print(args) #打包成元组
print(kargs) #打包成字典
fun(1,2,3,4,5, c=1,x=23,y='abc')
#输出结果:
# a = 1
# b = 2
# (3, 4, 5)
# {'c': 1, 'x': 23, 'y': 'abc'}
变量作用域
变量作用域:程序代码能访问该变量的区域。
局部变量
局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量。
def fun():
a = 1
print(a) # 1
fun()
# print(a) # NameError: name 'a' is not defined
def fun1():
global a
a = 1
print(a) # 1
fun1()
print(a) # 1
全局变量
全局变量:函数体外定义的变量,可作用于函数内外。
a = 1
def fun2():
print(a) # 1
fun2()
print(a)# 1
递归函数
递归函数:如果在一个函数的函数体内调用了该函数本身,这个函数就被称为递归函数。
组成:递归调用与递归终止条件。
调用过程:每递归调用一次函数,都会在栈内存分配一个栈帧,每执行完一次函数,都会释放相应的空间。
优缺点:缺点-占用内存多,效率低。优点-思路和代码简单。
例子: 使用递归计算阶乘:1 1 2 3 5 8 13
def fun(num):
if num == 1 or num ==2:
return 1
return fun(num-1) + fun(num-2)
print(fun(1)) # 1
print(fun(2)) # 1
print(fun(5)) # 5
print(fun(7)) # 13
print(fun(20)) # 6765
1425

被折叠的 条评论
为什么被折叠?



