Python函数学习
一、再次认识函数
1.1 函数概念
函数是将一些语句集合在一起的程序结构,是组织好的,可重复使用的,用来实现某些特定功能的代码段。
函数是一种编程抽象化过程,通过函数可以很有逻辑地做模块化的思考,更有利于理清高层次的抽象问题而避免同时处理底层的细节。因此,可以把函数理解为将底层操作封装起来,对操作或计算流程予以抽象化的机制。
函数的作用:
- 针对特定需求、可供重复利用的代码段
- 提高程序的复用性
- 减少重复性代码,提高开发效率
1.2 函数的定义和执行
1.2.1 函数的定义语法
# 语法
def 函数名(传入参数):
函数体
return 返回值
语法解释
• def (即define,定义)的含义是创建函数,也就是定义一个函数。
• arg (即argument,参数)的含义是给函数创建参数。
• return 即返回结果,不写的时候默认 return None或return
1.2.2 执行函数
实现函数功能的话需要进行执行函数:函数名(参数)
案例:
# 使用自定义函数完成:将求字符串中字符的功能封装到一个函数中,通过调用函数来完成获取字符串中字符的个数
str1 = 'Hello World'
str2 = 'Hello python!'
str3 = '每天进步一点点'
# 1. 定义求字符串中字符个数的函数
def len_str(args):
# args为该函数的一个形式参数,相当于一个占位符,调用的时候可以给中国风占位符传递实际的参数
#(1)定义一个记录字符个数的变量
count = 0
#(2)使用for循环统计字符串中字符的个数
for x in args:
count += 1 # 记录字符串中字符的个数的变量
#(3)跳出循环获取字符串中字符的个数
print(f'字符串{args}中有{count}个字符!')
# 2.使用该函数,调用函数传递不同的字符串实现字符个数的统计:函数名(传递实际的参数数据)
len_str(str1) # 字符串Hello World中有11个字符!
len_str(str2) # 字符串Hello python!中有13个字符!
len_str(str3) # 字符串每天进步一点点中有7个字符!
注意:
(1)函数中参数如不需要,可以省略
(2)返回值如不需要,可以省略
(3)函数使用步骤:函数必须先定义后使用
二、函数的参数及种类
2.1 函数参数概念
函数的参数是函数定义中用于接收输入值的占位符(形式参数)。当调用函数时,可以向参数传递实际的值,这些值被称为实参。
**传入参数的功能是:**在函数进行计算的时候,接受外部(调用时)提供的数据。
2.2 函数参数传入语法
def add(x, y):
result = x + y
print(result)
add(2, 5)
语法解析:
- 函数定义中,提供的x和y,称之为:形式参数(形参),表示函数声明将要使用2个参数。
- 参数之间使用逗号进行分隔
- 函数调用中,提供的5和6,称之为:实际参数(实参),表示函数执行时真正使用的参数值。
- 传入的时候,按照顺序传入数据,使用逗号分隔
- 传入参数的数量是不受限制的,可以不使用参数,也可以仅使用任意N个参数。
传入参数的时候,要和形式参数一一对应,用逗号隔开
2.3 函数参数使用
# 定义2数相加的函数,通过参数接收被计算的2个数字
def add(x, y):
result = x + y
print(f"{x} + {y} 的计算结果是:{result}")
# 调用函数,传入被计算的2个数字
num1 = float(input('请输入第一个数:'))
num2 = float(input('请输入第二个数:'))
# 调用求和函数
add(num1, num2)
2.4 函数中参数的种类
2.4.1 位置参数
位置参数:调用函数时根据函数定义的参数位置来传递参数。
注意点:传递的参数和定义的参数的顺序及个数必须一致。
# 1.定义一个显示学生基本信息的带参函数:位置参数
def stu_info(name,age,gender):
print(f'该学生的姓名为{name},年龄为{age}岁,性别为{gender}。')
# 2.调用位置参数:传递的参数和定义的参数的顺序及个数必须一致。
stu_info('lin',18,'女')
2.4.2 关键字参数
关键字参数:函数调用时通过 “键=值” 形式传递参数。
作用:可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。
# 1.定义一个带多个参数的函数
def show_stu(name, age, gender):
print(f'我的姓名是{name},我今年{age}岁了,我的性别是{gender}。')
# 2.调用函数:通过关键字参数进行传递,函数调用时,清除了参数的顺序需求,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
# (1)正确的传递
show_stu(name='lin',age=23,gender='女')
show_stu(gender='女',name='lin',age=23)
show_stu('lin',age=23,gender='女')
show_stu('lin',23,gender='女')
# (2)注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
# show_stu(name='lin',23,gender='女')
# show_stu(name='lin',age=23,'女')
报错:SyntaxError: positional argument follows keyword argument
2.4.3 缺省参数
缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值
作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值。
注意:
(1)函数调用时,如果为缺省参数传值则修改默认参数值,否则使用这个默认值。
(2)所有位置参数、关键字参数必须出现在默认参数前,包括函数定义和调用。
# 1.定义一个带多个参数的函数,给出一个参数的默认值
def show_stu(name, age, gender='男'):
print(f'我的姓名是{name},我今年{age}岁了,我的性别是{gender}。')
# 2.调用函数:通过缺省参数进行传递
# 1)正确的传递1:直接使用默认值,可以不传递缺醒参数的值
show_stu('lin',18)
print('-'*100)
# 2)正确的传递2:直接使用默认值,给出自定义的缺醒参数的值,使用实际参数值
show_stu('lin',18,'女')
show_stu('lin',18,gender='女')
show_stu('lin',age=18,gender='女')
show_stu(name='lin',age=18,gender='女')
print('-'*100)
# 错误的调用
# show_stu(name='lin',18)
# show_stu(name='lin',18,gender='女')
# show_stu('lin',age=23,'女')
# 3.如果一个函数中都是用了缺省参数,在调用这个函数的时候可以不用传递参数(使用的都是默认),当然也可以传递定义参数
def show_stu2(name='张三', age=18, gender='男'):
print(f'我的姓名是{name},我今年{age}岁了,我的性别是{gender}。')
# 正确调用1:不传递任何实参使用的就是默认参数值
show_stu2()
# 正确调用2:传递任自定义的参数
show_stu2('lin',24)
show_stu2('lin')
show_stu2('lin',24,gender='女')
2.4.4 不定长参数
不定长参数:不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。
作用:当调用函数时不确定参数个数时, 可以使用不定长参数。
不定长参数的类型:位置传递、关键字传递
注意点1:位置传递,传进的所有参数都会被args
变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递。
def user_info(*args):
print(args)
user_info('lin') # ('lin',)
user_info('lin',25) # ('lin', 25)
注意点2:关键字传递,参数是“键=值”
形式的形式的情况下, 所有的“键=值”
都会被kwargs接受, 同时会根据“键=值”组成字典。
def user_info(**kwargs):
print(kwargs)
user_info(name='lin', age=23, id=623)
三、函数的返回值
3.1 函数返回值的定义和代码实现
Python函数的返回值是指函数在执行完毕后,通过return
语句返回给调用方的结果。返回值可以是任何数据类型,包括数字、字符串、列表、字典、对象等。
当函数执行到return
语句时,函数会立即停止执行,并将return
后面的表达式或值作为返回值返回给调用方。调用方可以使用变量来接收函数的返回值,以便进一步处理或使用。
函数返回值的语法格式如下:
# 定义带返回值的函数
def 函数名(参数...):
函数体
return 返回的值
# 调用带有返回值的函数
变量 = 函数名(参数)
# 输出返回值
print(变量)
注意点:
①函数体在遇到return后就结束了,所以写在return后的代码不会执行。
②一个函数的默认返回值为None,return语句可以不用写,return是结束函数体代码的结束语,而且一个函数只能最多只有一个return
代码理解:
# 1.定义一个函数,给出函数返回值为一个字符串类型的数据
def show4():
return '这个函数返回的数据为一行字符串'
# 调用函数
show4() #直接调用函数(执行函数里面的所有内容),没有输出结果
print(show4()) # 经过print语句打印输出,这个函数返回的数据为一行字符串
print(type(show4())) # <class 'str'>
# print(type('这个函数返回的数据为一行字符串'))
3.2 None类型(默认无返回值)
函数返回值为None,可以当做False值来使用
# 1.定义一个函数,不使用return语句,函数执行后默认返回None值
def show1():
print('一个没有return语句的函数')
print('哈哈') # 没有return语句,哈哈可以正常被输出
# 调用函数
print(show1()) # None 就是该函数的返回值
# 2.定义一个函数,使用return语句,return后面不加任何东西,函数执行后返回None值
def show2():
print('一个有return语句的函数')
return
print('哈哈') # 该行代码不会被执行,原因是上面的return语句已经结束函数体中的内容
# 调用函数
print(show2()) # None就是该函数的返回值
# 3.定义一个函数,使用return语句,return后面加None值,函数执行后返回None值
def show3():
print('一个有return None语句的函数')
return None
print('哈哈') # 该行代码不会被执行,原因是上面的return语句已经结束函数体中的内容
# 调用函数
print(show3()) # None就是该函数的返回值
None类型的应用场景
- 用在函数无返回值上
# 1.定义一个检查年龄是否成年的函数
def check_age(age_num):
if age_num >= 18:
return '成年人'
else: # 未成年人返回None值
return None
# 2、键盘录入年龄调用函数
age = int(input('请输入您的年龄:'))
result = check_age(age)
print(result,type(result))
- 用在if判断上
if not result:
print('未成年人')
- 用于声明无内容的变量上
定义变量,但暂时不需要变量有具体值,可以用None来代替。
name = None
3.3 函数的多返回值
在Python中函数的返回值是可以有多个的,可以返回多个数据类型的返回值。默认使用一个tuple元组来接收这个多返回值的函数的。
语法格式:
按照返回值的顺序,写对应顺序的多个变量接收即可;
变量之间用逗号隔开;
支持不同类型的数据return。
举例说明:
# 1.定义一个多返回值的函数,默认使用一个元组进行接收
def func01():
# 使用return返回多个值
return 100, 88.88, True, 'hello', [12, 22, 55]
print(func01())
print(type(func01()))
# 执行结果:
(100, 88.88, True, 'hello', [12, 22, 55])
<class 'tuple'>
# 调用多返回值函数:使用多个变量进行接收,是什么变量返回值就返回什么类型
num1, num2, num3, num4, num5 = func01()
print(num1, type(num1)) # 100 <class 'int'>
print(num2, type(num2)) # 88.88 <class 'float'>
print(num3, type(num3)) # True <class 'bool'>
print(num4, type(num4)) # hello <class 'str'>
print(num5, type(num5)) # [12, 22, 55] <class 'list'>
四、函数的说明文档
函数是纯代码语言,想要理解其含义,就需要一行行的去阅读理解代码,效率比较低。我们可以给函数添加说明文档,辅助理解函数的作用。通过多行注释的形式,对函数进行说明解释。
语法如下:
def func(x, y):
'''
函数说明
:param x:形参x的说明
:param y:形参y的说明
:return:返回值的说明
'''
函数体
return 返回值
注意:内容应写在函数体之前。其中,
:param
用于解释参数,:return
用于解释返回值。
在PyCharm中查看函数说明文档,可以通过鼠标悬停,查看调用函数的说明文档。
五、函数的嵌套使用
# 1.定义第一个函数
def func01():
print('我是函数1')
# func02()
# func03()
func02()
# 2.定义第二个函数
def func02():
print('我是函数2')
func03()
# 3.定义第二个函数
def func03():
print('我是函数3')
# 使用函数:只需要调用func01这个函数同时可以得到func02和func03中的代码
# 1)实现方式1:在func01中继续调用func02和func03
# func01()
# 2)在func01中调用func02,在func02中调用func03
func01()
六、变量的作用域
6.1 什么是变量的作用域
变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用)。
6.2 变量作用域分类
变量的作用域主要分为两类:局部变量和全局变量。
6.2.1 局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效。
局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。
6.2.2 全局变量
所谓全局变量,指的是在函数体内、外都能生效的变量。
在一个函数中改变了全局变量的值,这个全局变量在函数执行结束后它的值不会被修改
# 1.局部变量:定义一个函数,在函数体内创建一个局部变量
def func01():
#定义一个局部变量
num = 77
print(num)
func01() # 执行的是上面的函数
# 强制在函数外面访问这个临时的num变量:不能访问函数中定义的局部变量
# 在func01函数执行完毕后是无法单独访问num这个变量的:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量
# print(num) # NameError: name 'num' is not defined. Did you mean: 'sum'?
# 2.定义一个全局变量:在函数体内、外都能生效的变量
name = '张三'
# 在函数内访问
def func02():
# 访问name这个全局变量
print(name)
func02() # 张三
# 在外面访问这个全局变量
print(name) # 张三
# 3.在一个函数中改变了全局变量的值,这个全局变量在函数执行结束后它的值不会被修改
def func03():
# 在函数里面定义的变量都是局部变量:作用范围只在该函数中有效
name = '李四'
print(name)
func03() # 李四
# 在外面访问这个全局变量
print(name) # 张三
print('-' * 100)
6.3 global关键字
使用 global关键字 可以在函数内部声明变量为全局变量。
name = '张三'
# 使用函数来修改全局变量的值
# 方法:使用global关键字将函数内部声明变量为全局变量
def func04():
# 在函数里面定义的变量都是局部变量:作用范围只在该函数中有效
# 使用global关键将函数内的临时变量变成全局变量
global name,name2
name = '王五'
print(name)
name2 = 'james'
func04() # 王五
# 在外面访问全局变量
print(name) # 王五
print(name2) # james
# 不报错,但是不符合编程语言的编写规范,不建议这样使用
七、匿名函数
7.1 lambda匿名函数的概念
在Python中,lambda函数是一种特殊的匿名函数(无名称函数),也称为lambda表达式。它是一种用于创建简单而临时的函数的方式,不需要使用def
关键字定义函数,并且可以在需要函数的地方直接使用。
Python的函数定义中,有名称的函数,可以基于名称重复使用,无名称的匿名函数,只可临时使用一次。
def
关键字,可以定义带有名称的函数lambda
关键字,可以定义匿名函数(无名称函数)
lambda创建匿名函数规则
- lambda只是一个表达式,函数体比
def
简单很多。 - lambda的主体是一个表达式,而不是一个代码块,所以不能写太多的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
- lambda定义的函数的返回值就是表达式的返回值,不需要return语句块
- lambda表达式的主要应用场景:赋值给变量、作为参数传入其它函数
lambda匿名函数的语法
Python中的 lambda匿名函数是可有参数,也可以没有参数的,下面为lambda匿名函数的语法定义。
- 无参数的lambda匿名函数语法
lambda:函数体(一行代码)
# 要获得lambda的返回结果,用print语句打印d
print(lambda : 100 + 200)
# 打印结果:打印的结果是一个内存地址值
<function <lambda> at 0x000002659CC7A050>
# 可以用一个变量接收lambda的返回值
func = lambda : 100 + 200
print(func)
# 如何将匿名函数的表达式的结果正确显示出来:匿名函数执行后的结果使用()调用
(lambda: print(100 + 200))() # 300 直接调用匿名函数
func01() # 300 通过变量进行调用,这个名称只是接收了匿名函数的值,没有用def定义
- 有参数的lambda匿名函数语法
lambda 传入参数:函数体(一行代码)
1)lambda 是关键字,表示定义匿名函数
2)传入参数表示匿名函数的形式参数,如:lambda x, y:函数体 。x、y表示接收2个形式参数
3)函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
func02 = lambda x, y : print(x + y)
(lambda x, y: print(x + y))(1, 2) # 3
func02(1, 2) # 3
func(lambda x, y: x + y) # lambda仅在这一次的调用中生效,没有办法二次使用,除非用一个变量来接收它
# 查看匿名函数的返回值
func03 = lambda x, y: x + y
result01 = func03(1, 2)
print(result01) # 3是匿名函数的返回值
func04 = lambda x, y: print(x + y)
result02 = func04(1, 2) # 3
print(result02) # None(print语句没有返回值)
lambda定义的函数的返回值就是表达式的返回值,不需要return语句块。lambda函数没有return语句,返回值默认是None。
lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
7.2 匿名函数实现列表推导式
# 1、定义一个列表
mylist = [1, 2, 3, 4, 5]
# 2、使用匿名函数将列表中的每一个元素乘以2
# 2.1 使用推导式完成
mylist_new1 = [x * 2 for x in mylist]
print(mylist_new1)
# 2.2 使用匿名函数将列表中的每一个元素乘以2
mylist_new2 = [(lambda v: v * 2)(x) for x in mylist]
print(mylist_new2)
# 2.3 使用map()函数进行转换,该函数的功能是将一个函数应用于一个序列的所有元素,比如列表,元组等
mylist_new3 = list(map(lambda x : x * 2,mylist))
# map函数处理后的数据是换一个迭代器对象,只需要使用list()函数进行转换即可得到
print(mylist_new3)
# 3、使用匿名函数过滤出列表中的偶数
print(mylist)
# 3.1 使用列表推导式完成
result01 = [x for x in mylist if x % 2 == 0]
print(result01)
# 3.2 使用匿名函数结合推导完成
result02 = [(lambda v: v % 2 == 0)(x) for x in mylist]
print(result02) # [False, True, False, True, False]
# 想要得到偶数数值,而不是布尔值
result03 = [x for x in mylist if(lambda v: v % 2 ==0)(x)]
print(result03)
7.3 函数作为参数传递
在Python函数的参数传递中,除了普通参数的传递外,还可以将定义好的函数作为另一个函数参数传递的对象,lambda匿名函数也可以作为参数传递给另外一个函数参数的使用。
7.3.1 def
定义的函数作为另一个函数参数传递
一个函数作为另一个函数的参数进行使用,调用的时候直接将一个函数名作为另外一个函数的实参即可
# 1.定义一个加法运算的有名称函数add01
def add01(x, y):
result = x + y
print(result)
# 2.定义一个减法运算的函数
def pre01(x, y)
result = x - y
print(result)
# 3.定义一个函数,即有加法的功能,又有减法的功能:使用函数作为参数传递
# 方式1:使用函数互相调用实现
def func01():
print('实现加法和减法的运算')
add01(1, 2)
pre01(3, 2)
func01()
# 方式2:使用函数作为参数传递
def func02(arg1, arg2): # arg1代表加法运算的函数,arg2是减法运算的函数
print('实现加法和减法的运算')
func02(add01(1, 2), pre01(3, 2))
# 方式3:直接传递函数的名称
def func03(arg1, arg2, x, y):
# arg1代表加法运算的函数,arg2是减法运算的函数,x和y就是加法和减法运算过程中的参数值
print('实现加法和减法的运算')
# 需要调用add01 和pre01函数
arg1(x, y)
arg2(x, y)
func03(add01, pre01, 3, 2)
7.3.2 lambda定义的函数作为另一个函数参数传递
匿名函数作为有名称函数的参数进行传递
# 1.定义一个加法运算的匿名函数add02变量
add02 = lambda x, y: f'加法运算:{x + y}'
# 2.定义一个有名称的func04函数
def func04(arg, a, b):
print('实现加法运算')
result = arg(a, b)
print(result)
func04(add02, 6, 1)
有名称函数作为匿名函数的参数进行传递
# 1.定义一个有名称的加法运算的函数add03
def add03(x, y):
result = x + y
return result
# 2.定义一个匿名函数func05
func05 = lambda arg, a, b: print(f'实现加法运算,结果为:{arg(a, b)}')
func05(add03, 5, 2)
匿名函数作为另一个匿名函数的参数进行传递
# 1.定义一个加法运算的匿名函数
add04 = lambda x, y: x + y
# 2.定义一个匿名函数为func06
func06 = lambda arg, a, b: arg(a, b)
result = func06(add04,8,8) # 用变量接收匿名函数的返回值
print(result)
# 或者这样写
func06 = lambda arg, a, b: print(arg(a, b))
func06(add04,8,8)