什么是函数
函数(function)是一个命名的代码块,用于执行某个任务或者返回一个数据,函数使用 def 关键字进行定义。
为啥使用函数
很多时候我们需要在程序中多次执行一个任务,而又不想多次重复编写相同的代码。此时,我们可以将这些代码封装成一个函数,然后在需要的时候使用该函数执行相应的操作。可以使用函数将大型程序拆分为更小更方便管理的模块。函数使得程序更加易于开发、阅读、测试以及维护。
怎么使用函数
定义函数
先上图
简单定义个打招呼的函数
def sayHello():
print("hello")
- 关键字def:函数定义以关键字 def 开始
- 函数名:随后是函数的名称,遵循驼峰法命名,函数定义以冒号结束。
- 函数体:函数定义之后的所有缩进代码都属于函数体
调用函数
当我们需要使用函数时,可以调用该函数。函数调用意味着执行函数内的代码
def sayHello():
print("hello")
sayHello() # 打印 hello
实参和形参
- 实参:调用函数时实际传入的参数
在上述例子中调用sayHello处,传入的"csdn"即为实参 - 形参:定义函数时,函数接收实参对应的参数,称之为形式参数。
在上述例子中定义sayHello(name),name即为形参,用以接收所有调用该函数是传入的实参,形参在函数体中作为指向实参的局部变量,只能在函数体中使用
函数返回值
在函数完成某个逻辑后,会产生这个逻辑执行后的结果,一般这个结果会作为其他逻辑或者程序继续执行的输入,所以函数需要在执行完成后返回这个结果,即函数的返回值。关键字return 返回结果。例如:
def sayHello(name):
return f"hello {name}"
# 调用函数
result = sayHello("csdn")
print(result) ## 打印hello csdn
如果在函数体中直接写print(),上述例子中效果上是一样的,都会打印结果,但是print并不是函数返回数据,这个结果不能被其他变量指向,仅仅是打印
函数参数
多数情况函数需要外部输入参数,以输入的参数完成指定的逻辑。例如,实现一个可以对输入的姓名打招呼的函数:
def sayHello(name):
print(f"hello {name}")
sayHello("csdn")# 调用该函数时,传入参数,完成打招呼的逻辑
# 打印 hello csdn
函数的参数可以是0个1个多个,多个参数的函数,形参之间用半角逗号隔开。函数的参数包含
- 必须参数
- 关键字参数
- 默认参数
- 不定长参数
# 定义一个加法函数
def add(a,b): # 形参为a,b 以,隔开
print("a = " + str(a))
print("b = " + str(b))
return a + b #返回结果
#1.必须参数
#按照对应形参的位置传入必须的实参
res = add(1,2) # 此处未指定形参,则按照对应位置,1传入给a,2传入给b
#打印
#a = 1
#b = 2
#3
#2.关键字参数
#此处需要注意形参名要写对,函数定义的什么形参就写什么形参,写错形参则报错
res1 = add(b = 1, a = 2) #此处指定关键字(形参),则无需按照对应位置,a就是2,b就是1。
print(res1)
#打印
#a = 2
#b = 1
#3
#3.默认参数
#还是定义一个计算两数加和函数,不过可以指定某个或多个形参有默认值,在调用处如果该形参未被传入值,则使用该默认值,如果传入了则使用传入的值,需要注意的是如果有多个形参有某些形参有默认值,默认值形参要放在后面
def add(a,b = 2): #此处形参b被赋了默认值1,a没有,且b要在a的后面
print("a = " + str(a))
print("b = " + str(b))
return a + b #返回结果
## 3.1调用函数
res3 = add(2,3) #传入两个实参,此处为a = 2 ,b = 3,因为b传入实参了,默认值不生效
print(res3)
#打印
#a = 2
#b = 3
#5
## 3.2调用函数
res4 = add(1) #此处只传入一个实参,则a = 1,b = 2,b的2是默认值
print(res4)
#打印
#a = 1
#b = 2
#3
不定长参数
这里单独拿出来说下不定长参数
1.什么是不定长参数?
顾名思义,传入的参数没有固定的长度,准确的说是没有固定的个数。
例如要计算一组数的和,但是不知道组数有多少个。则可以定义一个有不定长参数的函数:
#参数以一个星号开头,则传入的是一个元组(现在可以理解为是一组数据的集合,把一组数据放在一起了,格式是括号括在一起,例如(1,2,3))
def myFunc(m,*n):
"打印任何传入的参数"
print ("输出: ")
print (m)
print (n)
#调用函数
myFunc(1,2,3,4)
#打印
#输出:
#1
#(2,3,4) #第一个传入的实参给了m,后面的给了不定长参数(即元组)n
#参数以两个星号开头,则传入的是一个字典(现在可以理解为是以key value键值对组合的数据结构,例如{'a': 2, 'b': 3})
def myFunc1(m,**n):
"打印任何传入的参数"
print ("输出: ")
print (m)
print (n)
#调用函数
myFunc1(1,a=2,b=3);
#打印
#输出:
#1
#{'a': 2, 'b': 3}
例外需要注意,在不定长参数的函数定义中,*号可以单独出现,如果星号单独出现,则在星号后面的参数只能是以关键字参数的形式传入,即指定形参名,否则报错。
这里的星号在函数中并不是形参,一开始没有弄明白为啥单独搞个星号在函数括号里,后来查了下。这里的星号的作用是:Python 3 中可以定义一种只能以关键字形式来指定的参数,从而确保调用该函数的代码读起来会比较明确。这些参数必须以关键字的形式提供,而不能按位置提供,参数列表里的 * 星号,标志着位置参数的就此终结,之后的那些参数,都只能以关键字形式来指定(python3真贴心呢,哭唧唧)。
例如:
def myFunc2(a,b,*,c):
print(a)
print(b)
print(c)
#调用
myFunc2(1,2,c=3)#此处的1,2是星号前的位置传入形参,c=3是星号后的,标志着只能是以关键字形式来指定形参
#打印
#1
#2
#3
又查了下,在Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。(称做:强制位置参数)
在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
#正确调用
f(10, 20, 30, d=40, e=50, f=60)
#错误调用
f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式
匿名函数
Python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。下面的四个特点是俺百度的 ->_->
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法
lambda [arg1 [,arg2,.....argn]]:expression
示例
x = lambda a : a + 10
print(x(5))
#多参数匿名函数
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
运用
可以将匿名函数封装在一个函数内,这样可以使用同样的代码来创建多个匿名函数。
以下实例将匿名函数封装在 myfunc 函数中,通过传入不同的参数来创建不同的匿名函数:
def myfunc3(n):
return lambda a : a * n
mydoubler = myfunc3(2)
mytripler = myfunc3(3)
print(mydoubler(11)) # 结果为22
print(mytripler(11)) # 结果为33
递归函数
语法
指的是在函数体中可以调用自己的函数
def func4():
#函数体内调用自己
func4()
可以看到如果按照上面的写法,func4将一直调用自己,所以递归需要一个条件跳出调用自己的这个循环。
def func5():
# ...
if condition:
# 停止自我调用
else:
func5()
# ...
示例
求n (n>=1)到 10的和
def func6(n):
if n <= 1:
return n
else:
return func6(n-1) + n
res = func6(2)
print(res)
#结合三目运算
def func7(n):
return n + func7(n-1) if n > 0 else 0
res1 = func7(10)
print(res1)