三.函数进阶
0.定义
函数三要素:函数名,参数,返回值,其中只有函数名是必须要的,参数,返回值可以没有
语法:
def 函数名(参数):
函数体
return 返回值
1.多返回值:
按照返回值的顺序,写对应顺序的多个变量接收即可
变量之间用逗号隔开
支持不同类型的数据return
2.参数形式:
(1)位置参数:调用函数时根据函数定义的参数位置来传递参数,传递的参数和定义的参数的顺序及个数必须一致
即最基本的参数传递
def f (name,age,gender):print(f"你的名字是{name},你的年龄是{age},您的性别是{gender}")f("aa",18,"男")#你的名字是aa,你的年龄是18,您的性别是男
(2)关键字参数:函数调用时通过“键=值”形式传递参数.
作用:可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求.
def f (name,age,gender):print(f"你的名字是{name},你的年龄是{age},您的性别是{gender}")f(name= "小明",age= 18,gender= "男")#你的名字是小明,你的年龄是18,您的性别是男
f(age= 18,name= "小红",gender= "女")#你的名字是小红,你的年龄是18,您的性别是女
f(gender= "女",age= 18,name= "小槐")#你的名字是小槐,你的年龄是18,您的性别是女
(3)默认(缺省)参数
为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用).
作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值.
def f (name,age,gender = "男"):print(f"你的名字是{name},你的年龄是{age},您的性别是{gender}")f(name= "小明",age= 18)#你的名字是小明,你的年龄是18,您的性别是男
f(age= 18,name= "小红")#你的名字是小红,你的年龄是18,您的性别是男
f(gender= "女",age= 18,name= "武装直升机")#你的名字是小槐,你的年龄是18,您的性别是武装直升机
(4)不定长参数(可变参数):
主要有两种形式:一种是*parameter,另一种是**parameter
*parameter 表示接收任意多个实际参数并将其放到一个元组中
def printcoffee(*coffeename):print('\n我喜欢的咖啡有:')for item in coffeename:print(item)
printcoffee('蓝山','卡布奇诺','曼特宁','摩卡')"""我喜欢的咖啡有:
蓝山
卡布奇诺
曼特宁
摩卡
"""
**parameter 表示接收任意多个类似关键字参数一样显示赋值的实际参数,并将其放到字典中。
def printsign(**sign):print()for key,value in sign.items():print("[" + key + "]的星座是:" + value )
printsign(香凝='双鱼座',黛蓝='双子座',冷依依='射手座')
"""[香凝]的星座是:双鱼座
[黛蓝]的星座是:双子座
[冷依依]的星座是:射手座
"""
3.匿名参数
lambda关键字,可以定义匿名函数(无名称)只可临时使用一次。
语法:
解释:
lambda 是关键字,表示定义匿名函数
传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数
函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
#正常定义函数写
def func(sum):result = sum(1,2) print(result)def sum(x,y):return x+yfunc(sum)#3#用匿名函数写
def func2(sum):result = sum(1,2) print(result)
func2(lambda x,y : x+y )#3
#正常写
import math
def circlearea(r):result = math.pi*r*rreturn result
r = 10
print('半径为',r,'的圆面积为:',circlearea(r))#半径为 10 的圆面积为: 314.1592653589793#匿名函数写
import math
r = 10
result = lambda r:math.pi*r*r
print('半径为',r,'的圆面积为:',result(r))#半径为 10 的圆面积为: 314.1592653589793
4.常用内置函数(py自带)
过滤函数:filter()
是 Python 的一个内置函数,用于过滤序列,返回一个迭代器,其中包含满足指定条件的元素。
基本语法:
filter(function, iterable)
-
function
:一个函数(或lambda
表达式),用于定义过滤条件。 -
iterable
:可迭代对象(如列表、元组等),filter()
会遍历它并返回符合条件的元素。 -
例如:
-
scores = [75, 82, 90, 60, 58, 78] # 学生成绩列表 def selet(sc):return sc >= 60 def selet_scores():return list(filter(selet, scores)) print("及格成绩:", selet_scores())
5.函数文档字符串:
解释此函数用来做什么的,一般放在函数开头
使用__doc__属性查看
def my_function():'''函数名:my_function功能:测试参数:无返回值:无'''
print("函数输出成功")
my_function()
print(my_function.__doc__)
"""
函数输出成功函数名:my_function
功能:测试
参数:无
返回值:无
"""
6.闭包
1.定义:
闭包定义:如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数被认为是闭包,定义在外部函数内的但由内部函数引用或者使用的变量称之为自由变量。
如下例:
def func(name):def inner_func(age):print ('name:',name,'age:',age)return inner_func
bb=func("小明")
bb(24)#name: 小明 age: 24
9.3 案例 - 闭包的简单应用
这里面调用func的时候就产生了一个闭包——inner_func,并且该闭包持有自由变量——name,
因此这也意味着,当函数func的生命周期结束之后,name这个变量依然存在,因为它被闭包引用了,所以不会被回收。
2.nonlocal语句:
在 python 的函数内,可以直接引用外部变量,但不能改写外部变量,因此如果在闭包中直接改写父函数的变量,就会发生错误,如下例:
def outer_func():count =0def inner_func():count = count+1print("该程序能运行",count)return inner_funcouter_func()
result = outer_func()
result()
#UnboundLocalError: cannot access local variable 'count' where it is not associated with a value
由此引入了nonlocal关键字
def outer_func():count =0def inner_func():nonlocal count count= count+1print("该程序能运行","运行次数是:",count)return inner_funcouter_func()
result = outer_func()
result()#该程序能运行 运行次数是: 1
result()#该程序能运行 运行次数是: 2
PS:nonlocal 与 global 的区别在于 :nonlocal 语句会去搜寻本地变量与全局变量之间的变量,其会优先寻
找层级关系与闭包作用域最近的外部变量。
7.修饰器
本质上是闭包的函数应用
def dobi(qf):print("我是装饰器对应的函数dobi:" + qf())
#相当于qinfeng = dobi(qinfeng),简写成@dobi,相当于把qingfeng当做参数返回给dobi
@dobi
def qinfeng():return("我是被装饰的函数qinfeng")#我是装饰器对应的函数dobi:我是被装饰的函数qinfeng
步骤一: python 解释器发现@dobi,就去调用与其对应的函数( dobi 函数)
步骤二: dobi 函数调用前要指定一个参数,传入的就是@dobi下面修饰的函数,也就是 qinfeng()
步骤三: dobi() 函数执行,调用 qinfeng(),打印我是装饰器对应的函数dobi:我是被装饰的函数qinfeng