目录
一、函数的作用
什么是函数:函数(Function)是组织好的、可重复使用的、用来实现单一或相关联功能的程序段。我们知道 Python 提供了许多内置函数,比如print( )、input( )。我们也可以根据本节内容来自己创建函数,这种函数也叫用户自定义函数
函数的作用:程序开发中如果重复出现一些程序运算会造成系统的冗余,不利于程序的快捷与稳定运行。使用函数将重复出现的程序运算进行封装,设计成可供其他程序使用(调用)的独立程序段,当程序使用到该功能时直接调用,可以缩短开发时间,提升开发效率。
二、函数的定义与调用
函数是一个被指定名称的程序块,在要使用该程序块时,只需通过函数名调用该函数即可
1、函数的定义
- 函数代码块以 def 关键词开头,后接定义的函数名(满足标识符命名规则并做到顾名思义)和圆括号( )
- 圆括号( )用于存放形式参数,函数中任何需要传入的参数和自变量必须放在圆括号内,彼此之间使用 "," 隔开
- 函数的第一行语句可以用来解释函数的用途
- 函数体位于冒号之后,一般由多条可执行语句组成程序块,程序块内语句具有相同的缩进
- return [ 返回值 ] 结束函数,选择性地返回一个值给调用方。无 return 语句和不带表达式的 return 均会返回 None
- 返回值可以是一个表达式或值,不需要指定函数返回值的数据类型
def 函数名(形参列表):
# 解释函数用途
函数体
[returun [返回值]]
注意:在 Python 语法格式中,用方括号“[ ]”括起来的内容为可选择部分,即可以使用也可以省略
2、函数的调用
定义一个函数只给了函数一个名称,指定了函数里包含的参数和代码块结构。函数必须被调用后才会进行执行。由于函数返回了一个值,在调用时可以当做 Python 内部函数一样,将其写在表达式中即可
函数名(实参列表)
函数示例:
# 定义一个函数 hello(),输出"Hello Python!"(无参数,也不用return语句)
def hello(): # 定义函数
print("Hello Python!") # 函数体,函数功能
hello() # 调用hello()函数
# 运行结果:Hello Python!
# 定义一个矩形面积计算的函数area()
def area(h,w): # h,w分别为矩形的长和宽
return h*w # 返回长和宽的积
print('矩形的面积为:',area(5,3)) # 指定实参:h=5,w=3
# 运行结果:矩形的面积为:15
# 定义函数,实现计算4!+6!+8!的值
def jiecheng(x):
w = 1
for i in range(1,x+1):
w = w * i
return w
s = jiecheng(4)+jiecheng(6)+jiecheng(8)
print(f'4!+6!+8!={s}')
# 运行结果:4!+6!+8!=41064
注意:
- 根据不同的函数需求,参数和返回值可有可无
- 函数必须先定义后使用,因为 Python 是由上向下执行程序的
- 形参是在定义函数的时候拟定的变量,实参则是调用函数时对变量的赋值
- 调用函数时实参列表中传入数据的个数要与形参列表一致,且顺序必须和定义函数时一致
三、函数的值传递与引用传递
通常在调用函数时,调用函数与定义函数之间有数据的传递,即将调用函数的实参传递给定义函数,完成实参与形参的结合,然后才能执行函数调用程序
Python 中函数参数由实参传递给形参的过程是由参数传递机制来控制的。根据实参的类型不同,函数参数的传递分为值传递和引用传递(又称地址传递)两种
1、函数参数的值传递
如果实参的数据类型是不可变类型(字符串、数值、元组),则函数参数的传递方式为值传递。值传递就是将实参值的副本传入函数,不管在函数中如何对这个副本改变,实参值本身不会受任何影响
示例:
# 编写一个程序,分别传递一个数值和字符串,在函数更改他们的值
def test1(a,b): # 定义函数text1()
a = a * 2 # 在函数中改变变量的值
b = b + "qwer" # 在函数中改变变量的值
print("函数中的值 a=",a,"b=",b)
def main(): # 定义主函数,作为主程序的入口
a = 5 # 主程序中数值变量的初值
b = "asdf" # 主程序中数值变量的初值
print("主程序中的初值 a=",a,"b=",b)
test1(a,b) # 传值调用
print("主程序调用函数后的值 a=",a,"b=",b)
main()
# 运行结果:主程序中的初值 a= 5 b= asdf
# 函数中的值 a= 10 b= asdfqwer
# 主程序调用函数后的值 a= 5 b= asdf
AI解释代码: 以上代码定义了一个函数test1(),它接受两个参数a和b,并在函数内对a和b做某些操作并打印出来。主程序中定义了两个变量a和b,并打印出来。接着调用函数test1(),在函数中对a和b做了一些操作并打印出来。最后再打印一次a和b的值,可以看到在函数中对a和b的修改并没有影响主程序中a和b的值,这是因为传递给函数的是a和b的副本,所以函数中对副本的修改不会影响原始变量
2、函数参数的引用传递
如果实参的数据类型为可变对象(列表、字典),则函数参数的传递方式为引用传递。函数参数引用传递后,如果改变形参的值,则实参的值也会一同改变
示例:
# 编写一个程序,分别传递一个数值和一个列表,在函数更改他们的值
def test2(a,b): # 定义函数text2()
a = a * 2 # 在函数中改变变量的值
b.append('green') # 在函数中改变变量的值
print("函数中的值 a=",a,"b=",b)
def main(): # 定义主函数,作为主程序的入口
a = 5 # 主程序中数值变量的初值
b = ['red','yellow','blue'] # 主程序中数值变量的初值
print("主程序中的初值 a=",a,"b=",b)
test2(a,b) # 传值调用
print("主程序调用函数后的值 a=",a,"b=",b)
main()
# 运行结果: 主程序中的初值 a= 5 b= ['red', 'yellow', 'blue']
# 函数中的值 a= 10 b= ['red', 'yellow', 'blue', 'green']
# 主程序调用函数后的值 a= 5 b= ['red', 'yellow', 'blue', 'green']
AI解释代码: 在 main() 中,首先定义了变量 a 和 b,并分别赋初值为 5 和 ['red','yellow','blue']。然后输出了这两个变量的初值。 接着调用了函数 test2(a,b)。在函数 test2() 中,对输入的参数进行了修改,将 a 的值乘以了 2,并在 b 的末尾添加了 'green'。然后输出了修改后的结果。 最后再次输出了 a 和 b 的值,可以看到在函数中对 a 进行的修改并没有影响到主程序中变量的值。因为在 Python 中,整数和字符串都是不可变类型,所以对它们的修改只在函数内部生效。但是对于可变对象比如列表b,在函数内部进行的操作会改变原始参数在函数外部的值
四、参数的传递
在Python 函数中,实参向形参的传递方式有4种:按位置传递、按默认值传递、按关键字传递和按可变参数传递
1、按位置传参
该类函数实参必须以正确的顺序传入函数,调用时实参的数量必须形参保持一致,否则将会出现语法错误
示例:
# 定义一个函数,可以计算任何⽤户指定的两个数字的和,同时明确形式参数a和b
def add1(a, b):
result = a + b
print(result)
add1(5, 10) # 调⽤函数时传⼊了真实的数据5和10
add1(5) # 调用函数时只传入一个实参
# 运行结果: 15
# 报错:add1() missing 1 required positional argument: 'b'
2、按默认值传参
调用函数时,默认参数的值如果没有传入,则被认为是默认值
示例:
def fucn1(name="张三", age=18):
print(f"大家好,我是{name},今年{age}岁了")
fucn1() # 大家好,我是张三,今年18岁了
fucn1(name="李四") # 大家好,我是李四,今年18岁了
fucn1(age=20) # 大家好,我是张三,今年20岁了
fucn1(name="李四",age=20) # 大家好,我是李四,今年20岁了
3、按关键字传参
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值
示例:
def fucn1(name, age):
print(f"大家好,我是{name},今年{age}岁了")
fucn1(name="李四",age=20) # 大家好,我是李四,今年20岁了
4、按可变参数传参
一般情况下,在定义函数时形参的个数是可以确定的,但是也有在定义函数时不能确定形参个数的情况,这个时候就需要用到可变参数(又称不定长参数),即传入函数中的实参可以是任意多个
在 Python 中,在形参前加一个星号(*)或两个星号(*)来指定函数可以接收任意数量的实参。
示例:
def demo1(*args):
print(args)
demo1(1,2,3,4,4,5)
# 运行结果:(1,2,3,4,4,5)
def dem1(num, *args, **kwargs):
print(num)
print(args)
print(kwargs)
demo2(1, 2, 3, a=5, b=6, c=7)
# 运行结果:1
# (2, 3)
# {'a': 5, 'b': 6, 'c': 7}
注意:
- 不带*的形参为普通参数。调用时实参可选择前3种方式传递使用
- 形参前加一个*的,表示这是一个元组参数,在传入额外的参数时可以不用指明参数名,直接传入参数值即可
- 形参前加两个*的,表示这是一个字典参数(键值对参数),传入时需要指定参数名
五、函数的返回值
函数的定义和调用是对传入的数据进行处理,处理完成后程序也就结束了。但是我们使用函数的目的经常是需要将处理结果反馈给我们,这就需要用到 return 语句返回函数值并退出函数
示例:
# 定义一个add()函数,既可以用来计算两个数值的和,也可以连接两个字符串,返回计算结果
def add(a,b):
c = a + b
return c
c = add(1,2)
print(c)
print(add("abcd","1234"))
# 运行结果:3
# abcd1234
另外函数的返回值还可以作为参数传递给其它函数。函数的返回值可以存储到变量中供其他代码使用,而打印函数,打印的就是函数的返回值
示例:
# 将func2的返回值作为实参传递给func1
def func1(num): # 形参
print(num)
print(num + 100)
return "这是func1的返回值"
def func2():
return 100
print(func1(func2()))
# 运行结果:100
# 200
# 这是func1的返回值
六、变量作用域
在程序中定义的变量是有作用范围的,变量起作用的范围成为变量的作用域。变量的作用域表现为有的变量可以在整个程序或其他程序中进行引用(全局变量),有的变量则只能在局部范围内引用(局部变量)。一个变量在函数外部定义和在函数内部定义,其作用域是不同的
1、全局变量
全局变量指的是能同时作用于函数内外的变量。可以在函数中使用 global 关键字来定义或修改全局变量
示例:
num = 10
def demo():
result = num + 20
print(result)
demo()
# 运行结果:30
2、局部变量
局部变量指的是在函数内部定义的普通变量,该变量只在该函数内起作用,别的函数不可访问。局部变量与函数外具有相同名称的其他变量没有任何关系,彼此互不干扰
示例:
num = 5
def demo2():
global num # 声明num为全局变量
num = 10 # 局部变量
demo2()
result = num + 20
print(result)
# 运行结果:30
七、函数的嵌套调用
所谓函数嵌套调用指的是⼀个函数里面又调用了另外⼀个函数