函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。能提高应用的模块性,和代码的重复利用率。Python提供了许多内建函数,比如print()。但也可以自己创建函数,这被叫做用户自定义函数。
1.定义函数
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None
2.调用函数
函数在定义完成后不会立刻执行,直到被程序调用时才会执行
语法格式:
函数名([参数列表])
eg:
# 定义函数
def printme(str):
"打印任何传入的字符串"
print(str)
return
# 调用函数
printme("调用自定义函数")
printme("再次调用同一函数")
2.1 嵌套调用
函数内部也可以调用其他函数,这被称为函数的嵌套调用。
eg:
其中子函数调用注意缩进
可以在内部嵌套定义另外一个函数,此时嵌套的函数称为外层函数,被嵌套的函数称为内层函数
函数外部无法直接调用内层函数 只能通过外层函数间接调用内层函数
3.函数参数的传递
定义函数时设置的参数称为形参,将调用函数时传入的参数称为实参。函数的参数传递是指将实际参数传递给形式参数的过程。
函数参数的传递可以分为位置参数传递、关键字参数传递、默认参数传递、参数的打包与解包以及混合传递。
3.1 位置传参
- 将第一个实参传递给第一个形参,将第二个实参传递给第二个形参
eg:
def get_max(a, b):
if a > b:
print(a,"是较大的值!")
else:
print(b,"是较大的值!")
get_max(8, 5)
结果如下:
- 使用符号“/”来限定部分形参只接收采用位置传递方式的实参。
eg:
3.2 关键字传参
通过“形参=实参”的格式将实参与形参相关联,将实参按照相应的关键字传递给形参。
eg:
结果如下:
3.3 默认传参
在定义时可以指定形参的默认值,即在被调用时可以选择是否给带有默认值的形参传值,若没有给带有默认值的形参传值,则直接使用该形参的默认值。
eg:
def connect(ip, port=8080):
print(f"设备{ip}:{port}连接!")
connect(ip="127.0.0.1")
connect(ip="127.0.0.1", port=3306)
结果如下:
3.4 打包与解包
在定义时无法确定需要接收多少个数据,那么可以在定义函数时为形参添加“*”或“**”:
“*” —— 接收以元组形式打包的多个值
“**”—— 接收以字典形式打包的多个值
虽然函数中添加“*”或“**”的形参可以是符合命名规范的任意名称,但建议使用*args和**kwargs。
若函数没有接收到任何数据,参数*args和**kwargs为空,即它们为空元组或空字典。
- 打包
“ * ”
“ ** ”
- 解包
实参是元组 → 可以使用“*”拆分成多个值 → 按位置参数传给形参
实参是字典 → 可以使用“**” 拆分成多个键值对 → 按关键字参数传给形参
eg:
3.5 混合传递
在定义函数或者调用函数的时候可以混合使用,其使用规则如下:
1.按位置参数传递的方式。
2.按关键字参数传递的方式。
3.按默认参数传递的方式。
4.按打包传递的方式
在定义函数时:普通函数 > 带有默认值的参数 > 带有“*”标识的参数 > 带有“**”标识的参数
eg:
4. 函数的返回值
- return语句会在函数结束时将数据返回给程序,同时让程序回到函数被调用的位置继续执行。
- 如果函数使用return语句返回了多个值,那么这些值将被保存到元组中
eg:
def cacluate(*num):
l=[]
avg=sum(num)/len(num)
for i in num:
if i>avg:
l.append(i)
return avg,l
count=cacluate(1,2,3,4,5,6,7)
print(count)
结果如下:
5. 变量作用域
变量定义的位置所处的有效范围称为变量的作用域。
作用域的不同可以分为局部变量和全局变量
5.1 局部变量
只能在函数内部使用
函数执行结束之后局部变量会被释放,此时无法再进行访问。
不同函数内部可以包含同名的局部变量,它们相互独立,互不影响。
eg:
错误示范:
正确示范:
def test_one():
number=10
print(number)
def test_two():
number=20
print(number)
test_one()
test_two()
5.2 全局变量
全局变量可以在整个程序的范围内起作用,它不会受到函数范围的影响。
全局变量在函数内部只能被访问,而无法直接修改。
eg1:
eg2:
6. global关键字和nonloc关键字
能间接修改全局变量或在嵌套函数的外层函数声明的变量
6.1 global关键字
可以将局部变量声明为全局变量
6.2 nonlacal关键字
在局部作用域中修改嵌套作用域中定义的变量
7. 递归函数
可以直接或间接地调用其他函数。若函数内部调用了自身,则这个函数被称为递归函数。
使用时需要满足两个基本条件:
递归公式是求解原问题或相似的子问题的结构;
边界条件是最小化的子问题,也是递归终止的条件。
执行时分为两个阶段:递推和回溯
eg:
#递归函数
def fun(num):
if num==1:
return 1
else:
return num * fun(num-1)
num=int(input("请输入一个整数:"))
result=fun(num)
print("5!=%d"%result)
结果如下:
8. 匿名函数
无需定义标识符的函数,它与普通函数一样可以在程序的任何位置使用
与普通函数不同的是:
- 匿名函数没有名称而普通函数有
- 匿名函数只能是一个表达式且实现功能比较简单
- 匿名函数不能被其他程序所使用
语法格式:
lambda <形式参数列表> :<表达式>
eg:
#匿名函数
temp=lambda x :pow(x,2)
temp(10)
print(temp)
结果如下: