函数
函数是一段可重用的代码。可以通过输入的参数值,返回需要的结果,并可存储在文件中供以后使用。几乎任何Python代码都可放在函数中。Python为函数提供了强大支持。
-
函数的定义及调用
- 格式:def 函数名(形参表):
函数体语句序列
[return 表达式] #可选项,即有的函数可以没有返回值。 - 函数调用:
函数名(实参表) - 说明:
- 函数必须先定义,后使用;
- 函数名与变量名的命名规则相同,只能包含字母、数字和下划线_,且不能以数字打头。
- 向函数传递参数时,Python采用按引用传递的方式。这意味着当传递参数时,函数将使用新变量名来引用原始值。
代码演示如下:
import math # 导入math模块(python文件) # 定义函数 def circle_size(r): # 接收半径值,使用形式参数r来接收 return math.pi * r ** 2 # 计算圆的面积,并返回计算结果 result = circle_size(5) # 调用函数,并传递实际参数 print("圆的面积是:",result) print("两个圆的面积和是:",circle_size(5)+circle_size(6)) print(math.pow(3,3)) # 幂运算 def add(a,b): return a + b x,y = 1,2 print(x,"+",y,"=",add(x,y))
结果如下:
圆的面积是: 78.53981633974483 两个圆的面积和是: 191.63715186897738 27.0 1 + 2 = 3
- 格式:def 函数名(形参表):
-
形式参数
-
普通参数
def add(x,y):
return x + y -
默认值参数
- 函数的参数支持默认值。当某个参数没有传递实际的值时,函数将使用默认参数计算。
- 带默认值的参数不能位于普通参数前面。
-
位置可变参数(*)
在形式参数名称前加一个星号*,则代表使用该形式参数可以接收任意多个参数,而且接收的参数将会以元组的方式组织。
def func(*args):# args以元组的方式组织传入的实参
print(args)
func(1,2,3,4,’abc’) -
关键字可变参数(**)
在形式参数名称前加两个星号** 可以接收任意多个传入的键-值对参数(关键字实参),而且接收的参数将会以字典的方式组织。
def func(**kwd)# kwd以字典的方式组织传入的关键字实参
print(kwd)
func(name=‘tom’,age=20)注意:当位置可变参数(*args)和关键字可变参数(**kwd)一起使用时候,必须先声明位置可变参数(*args),最后声明关键字可变参数(**kwd)
默认值形式参数代码演示如下:
# 默认值形式参数 def hi(name,greet="hello"): # greet参数就是默认值参数 print(name+","+greet) hi("张三") hi("李四","奥利给~~~") # 还传递了一个打招呼的参数 hi("王五",greet="how are you?") # 通过指定参数名称的方式传递参数 hi(name="alice",greet="ha ha") # 也可以指定多个参数名传值 hi(greet="welcome~~",name="tom") # 调用函数的时候,只要能与函数的形参名匹配即可
结果如下:
张三,hello 李四,奥利给~~~ 王五,how are you? alice,ha ha tom,welcome~~
位置可变形式参数代码演示如下:
# 位置可变参数 # 位置可变参数可以接收任意多个参数 def func(*a): # 形式参数是位置可变参数 print("a的类型是",type(a)) print("a为:",a) func() print("*"*30) func(1) print("*"*30) func(1,2,3,"hello",["apple","banana"])
结果如下:
a的类型是 <class 'tuple'> a为: () ****************************** a的类型是 <class 'tuple'> a为: (1,) ****************************** a的类型是 <class 'tuple'> a为: (1, 2, 3, 'hello', ['apple', 'banana'])
关键字可变参数代码演示;
# 关键字可变参数接收传入的任意多个关键字实参 def func(**kwd): print("kwd的类型是:",type(kwd)) print("kwd是:",kwd) func() print("*"*30) func(fruit="apple",sport="football",country="China")
结果如下:
kwd的类型是: <class 'dict'> kwd是: {} ****************************** kwd的类型是: <class 'dict'> kwd是: {'fruit': 'apple', 'sport': 'football', 'country': 'China'}
多种参数的顺序演示代码如下:
# 多种参数的顺序 def func(a,b,greet="hello",*args,**kwd): print("a是:",a) print("b是:", b) print("greet是:", greet) print("args是:", args) print("kwd是:", kwd) func(1,2,3,4,5,6,"hi",fruit="apple",sport="football")
结果如下:
a是: 1 b是: 2 greet是: 3 args是: (4, 5, 6, 'hi') kwd是: {'fruit': 'apple', 'sport': 'football'}
实参解构
- 给函数提供实参的时候,可以使用*或者**,把参数解构
- 非字典类型使用*解构(拆散)成位置参数
- 字典类型使用**解构(拆散)成关键字参数
代码演示如下:
# 实参解构(拆散) def func(a,b,c,d): print("a=",a) print("b=",b) print("c=",c) print("d=",d) things = ["apple","banana","cup","dog"] func(*things) # 调用函数时,在列表(元祖、集合)前加一个星号*,就会解构里面的值(将里面的数据拆出来) print("*"*30) func(*"ABCD") # 字符串也可以解构 print("*"*30) # 下面的代码相当于 func(a="aaa",c="ccc",d="ddd",b="bbb") func(**{"a":"aaa","c":"ccc","d":"ddd","b":"bbb"}) # 对于字典类型,使用双星号**进行实参解构
结果如下:
a= apple b= banana c= cup d= dog ****************************** a= A b= B c= C d= D ****************************** a= aaa b= bbb c= ccc d= ddd
-
递归函数
-
递归的概念
- 递归函数可以在函数主体内直接或间接地调用自己,即函数的嵌套是函数本身。
- 递归是一种程序设计方法,使用递归可以减少重复的代码,使程序变得简洁。
- 递归的过程分为两个阶段:递推和回归。
- 递归函数的原理:
- 第一阶段,递归函数在内部调用自己。每一次函数调用又重新开始执行此函数的代码,直到某一级递归程序结束。
- 第二阶段,递归函数从后往前返回。递归函数从最后一级开始返回,一直返回到第一次调用的函数体内。即递归函数逐级调用完毕后,再按相反的顺序逐级返回。
-
递归的实现
- 一个问题能否用递归实现,看其是否具有下面的特点:
- 需有完成任务的递推公式。
- 结束递归的条件。
- 编写递归函数时,程序中必须有相应的语句:
- 一个递归调用语句。
- 测试结束语句。先测试,后递归调用。
- 一个问题能否用递归实现,看其是否具有下面的特点:
-
例题
递归公式:
1 n=1
n!=
n*(n-1)! n>1
例如,使用递归计算5!的过程:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y20wBcHb-1593576572040)(C:\Users\Lenovo\Desktop\图片2.png)]
代码演示如下:
# 递归调用(函数自己调用自己)
# 题目:计算5的阶乘5!
def compute(n):
if n == 1:
return 1
return n * compute(n-1)
print("5的阶乘是:",compute(5))
结果如下:
5的阶乘是: 120
函数嵌套定义,内部函数直接引用外部函数的变量:
代码演示如下:
# 函数内部可以定义其他函数,内部函数可以直接访问外部函数的变量
def outer(): # 外部函数
a = 100
b = 50
def inner(): # 内部函数
return a + b # 内部函数可以直接访问外部函数的变量
return inner
print(outer()()) # 结果是什么?
print(type(outer))
结果如下:
150
<class 'function'>
Generator函数
- Generator函数的作用是一次产生一个数据项,并把数据项输出,迭代性能更佳。
- 格式:
def 函数名(参数列表):
…
yield 表达式 - 说明:Generator函数的定义与普通函数的区别只是在函数体内使用yield生成数据项。 Generator函数可以被for循环中遍历,且可以通过next()方法执行到yield处,并返回yield生成的数据内容,然后暂停(挂起)在这个地方,直到下一次调用next()方法
代码演示如下;
# 生成器函数——内部含有yield的函数
def func():
print("aaa")
yield "hello" # 返回数据,并挂起(暂停)函数
print("bbb")
yield "Python" # 返回数据,并挂起(暂停)函数
print("ccc")
yield "Game" # 返回数据,并挂起(暂停)函数
print("ddd")
gen = func() # 调用生成器函数,返回的是一个generator对象
data1 = gen.__next__() # 通过__next__()方法执行到yield处,并接收yield返回的数据
print("=====>",data1)
data2 = gen.__next__() # 继续从刚才函数挂起的地方执行,直到遇到下一个yield
print("=====>",data2)
data3 = gen.__next__() # 继续从刚才函数挂起的地方执行,直到遇到下一个yield
print("=====>",data3)
#gen.__next__() # 继续从刚才函数挂起的地方执行,直到遇到下一个yield
结果如下:
aaa
=====> hello
bbb
=====> Python
ccc
=====> Game
其他小知识点
** : 表示次方
pow(3,2) 表示3的平方
3**2 表示 3的平方
默认参数不能放在普通参数前面,定义与调用时都不能。
.next() # 继续从刚才函数挂起的地方执行,直到遇到下一个yield
print("=>",data2)
data3 = gen.next() # 继续从刚才函数挂起的地方执行,直到遇到下一个yield
print("=>",data3)
#gen.next() # 继续从刚才函数挂起的地方执行,直到遇到下一个yield
结果如下:
aaa
=====> hello
bbb
=====> Python
ccc
=====> Game
# 其他小知识点
** : 表示次方
pow(3,2) 表示3的平方
3**2 表示 3的平方
默认参数不能放在普通参数前面,定义与调用时都不能。