1、闭包函数
如果内函数使用了外函数的局部变量,并且外函数把内函数返回的过程就叫闭包
形成闭包的条件:
1.函数嵌套
2.将内函数作为返回值返回
3.内函数必须使用外函数的局部变量
python
def out_fun(x):
def in_fun(y):
return y**x
return in_fun
print(out_fun(2)(3))
2、lambda匿名函数
没有名字的函数,一般函数体只有一条语句,一个返回值,用于实现简单功能
代码示例:
python
print((lambda x:x*x)(9))#9的平方
fun1=lambda x:x*2
print(fun1(88))#88的二倍
fun2=lambda :print("我是匿名函数")
fun2()
fun3=lambda :3
print(fun3)#返回的<function <lambda> at 0x0000019CC46F9940>
print(fun3())#返回值是3
fun4 = lambda *num : sum(num)
print(fun4(1,2,3,4,5))
fun5 = lambda **stus : stus
print(fun5(zhangsan=18, lisi=20, wangwu=19))
fun6 = lambda a,b=1 : a+b
print(fun6(3))
print(fun6(3,8))
# 使用匿名函数接收两个参数a和b,返回a、b的较大值
fun7 = lambda a, b: max(a,b)
print(fun7(10,20))
# python中的三元运算符
# 结果1 if 条件 else 结果2
fun8 = lambda a, b : a if a>b else b
print(fun8(13,10))
lambda函数的特性
- lambda函数是匿名的,即它是没有名字的函数,并且自带return。
- lambda函数可以使用任意数量的参数,但只能包含一个表达式。
- lambda函数返回一个值,这个值就是表达式的结果。
- lambda函数的生命周期很短,调用后立即被回收。
3、高阶函数
1. map()
--- 将函数应用于每个元素
map()
用于将一个指定的函数应用到可迭代对象的每个元素上,返回一个 迭代器,其元素是原始可迭代对象的每个元素经过函数处理后的结果。
语法:
python
map(function, iterable, ...)
-
function
:一个函数,它接受可迭代对象的元素作为输入,并返回处理后的结果。 -
iterable
:一个可迭代对象,如列表、元组等。如果有多个可迭代对象,它们会逐一传递给function
。
示例:将列表中的每个数字平方
python
lst = [1, 2, 3, 4]
result = map(lambda x: x ** 2, lst)
print(list(result)) # 输出: [1, 4, 9, 16]
map()
的特点:它逐一处理每个元素,并返回一个新的迭代器,而不是修改原始列表。
2. filter()
--- 过滤符合条件的元素
filter()
用于根据指定条件从可迭代对象中过滤出符合条件的元素,返回一个 迭代器,其中包含所有符合条件的元素。
语法:
python
filter(function, iterable)
-
function
:一个函数,它接受可迭代对象的元素,并返回True
或False
。True
表示保留该元素,False
表示过滤掉该元素。 -
iterable
:一个可迭代对象,如列表、元组等。
示例:过滤掉列表中的偶数
python
lst = [1, 2, 3, 4, 5]
result = filter(lambda x: x % 2 != 0, lst)
print(list(result)) # 输出: [1, 3, 5]
filter()
的特点:它根据条件过滤元素,并返回一个新的迭代器,仅包含符合条件的元素。
3. reduce()
--- 将多个元素累积为一个值
reduce()
用于将一个二元函数应用于可迭代对象的元素,将多个元素"缩减"(累积)成一个单一的值。它返回的是最终的结果,而不是一个集合。
语法:
python
from functools import reduce
reduce(function, iterable, [initializer])
-
function
:一个二元函数,它接受两个参数,返回一个新的结果。 -
iterable
:一个可迭代对象,如列表、元组等。 -
initializer
(可选):一个初始值,将作为function
的第一个参数,默认为None
。
示例:计算列表中所有数字的和
python
from functools import reduce
lst = [1, 2, 3, 4, 5]
result = reduce(lambda x, y: x + y, lst)
print(result) # 输出: 15
-
reduce()
的特点:它将可迭代对象的所有元素依次应用于二元函数,最终返回一个值。它并不返回一个集合,而是返回一个"缩减"的结果。
三者的对比:
功能 | map() |
filter() |
reduce() |
---|---|---|---|
目的 | 将函数应用于每个元素,返回新的元素集合 | 根据条件过滤出符合要求的元素 | 将多个元素累积成一个单一的值 |
输入 | 一个函数和一个可迭代对象 | 一个函数和一个可迭代对象 | 一个二元函数和一个可迭代对象 |
返回 | 一个可迭代对象,包含每个元素经过函数处理后的结果 | 一个可迭代对象,包含符合条件的元素 | 一个单一的值,表示对所有元素的累积结果 |
典型用法 | 对每个元素进行某种转换 | 筛选符合条件的元素 | 执行某种累积操作,如求和、求积、求最大值等 |
使用例子 | [1, 2, 3] -> [2, 4, 6] (每个元素乘以 2) |
[1, 2, 3, 4] -> [1, 3] (只保留奇数) |
[1, 2, 3, 4] -> 10 (所有元素求和) |
4、装饰器
4.1装饰器含义
在python中,装饰器本质是一个特殊的嵌套函数,它接收一个函数【被装饰的函数】做参数,并返回一个新的函数【装饰后的函数】
装饰器的最大作用:在不改变原有函数【被装饰的函数】的基础上给它添加新的功能。
4.2 装饰器的基本用法
python
# 装饰器
def out_fun(function):
def in_fun():
print("挂上一颗星星")
function()
print("挂上一个礼物盒")
return in_fun
# 被装饰函数
def my_tree():
print("简简单单一棵树")
# 第一种调用方式
out_fun(my_tree)()
# 问:第一种调用方式,被装饰函数真的装饰了吗
my_tree() # 并没有新增功能
# 第二种调用方式
my_tree = out_fun(my_tree)
# 问:第二种调用方式,被装饰函数真的装饰了吗
my_tree()
4.3 装饰器语法糖
语法糖是由编程语言提供的,可以让代码更加简洁、高效、易读和易写。语法糖不改变不会带来新的功能,也不会改变编程的结果,但是使用它会更加方便。
python中有很多语法糖,已用的有:
(1)列表推导式
(2)集合推导式
(3)字典推导式
(4)f-string print(f"{}")
(5)解包
(6)装饰器
语法格式:
@装饰器函数名
def 被装饰函数名:
代码块
其实就是在被装饰函数的上面加一句话------@装饰器
python
# 装饰器
def out_fun(function):
def in_fun():
print("挂上一颗星星")
function()
print("挂上一个礼物盒")
return in_fun
# 被装饰函数
@out_fun
def my_tree():
print("简简单单一棵树")
my_tree()
4.4 被装饰函数有参数
若被装饰函数有参数,那么装饰器的内部函数也需要有参数,保证在内部调用被装饰函数的时候能正确传参。
4.4.1 被装饰函数有一个参数
python
def out_fun(function):
def in_fun(x):
print("挂上一颗星星")
function(x)
print("挂上一个礼物盒")
return in_fun
# 被装饰函数
@out_fun
def my_tree(x):
print(f"简简单单{x}棵树")
my_tree(3)
4.4.2 被装饰函数有未知个参数
python
import time
# 装饰器
def out_fun(function):
def in_fun(*args, **kwargs):
start = time.time()
function(*args, **kwargs)
end = time.time()
print(end - start)
return in_fun
# 被装饰函数1
@out_fun
def fun1(x):
time.sleep(1)
print(x)
fun1(1)
# 被装饰函数2
@out_fun
def fun2(x, y, z):
time.sleep(1)
print(x + y + z)
fun2(1,2,3)
4.5 装饰器带参数
上面3.4是被装饰函数带有参数,我们在装饰器内部函数设置参数,以保证参数的正确传递。
现在装饰器要带有参数,而且装饰器的外部函数要接收被装饰函数的函数名,内部函数要接收被装饰函数的参数,那么为了保证装饰器参数、被装饰函数参数的正确传递,我们在装饰器外部函数再嵌套一层函数,用于接收装饰器参数。
python
# 装饰器
def decoration(dec_arg):
def out_fun(function):
def in_fun(x):
print(dec_arg)
print("挂上一颗星星")
function(x)
print("挂上一个礼物盒")
return in_fun
return out_fun
# 被装饰函数
@decoration("我是装饰器的参数")
def my_tree(x):
print(f"简简单单{x}棵树")
my_tree(3)
4.6 装饰器嵌套
已学的嵌套:列表、字符串、元组、集合、字典、函数、循环、选择
装饰器嵌套就是被装饰函数 可以 被多个装饰器装饰。
python
# 装饰器1
def out_fun_1(function):
def in_fun_1(*args, **kwargs):
print("装饰器1开始调用")
function(*args, **kwargs)
print("装饰1结束调用")
return in_fun_1
# 装饰器2
def out_fun_2(function):
def in_fun_2(*args, **kwargs):
print("装饰器2开始调用")
function(*args, **kwargs)
print("装饰2结束调用")
return in_fun_2
# 嵌套装饰 被装饰函数
@out_fun_1
@out_fun_2
def my_tree(x):
print(f"{x}棵树")
my_tree(3)
4.7 类装饰器
除了可以自定义一个新的函数用作装饰器之外,也可以将一个类作为装饰器,为被装饰的函数添加新的功能。类装饰器通过实现类的__call__方法,使得类的实例可以被当作函数来调用,丛而实现对其他函数的装饰。