目录
一、闭包
闭包是一种特殊的函数,而函数是一段可以重复使用的代码,它可以接受输入(参数),并返回输出(结果)。
闭包不仅包含函数的代码,还包含了函数定义时所在的环境。这个环境包括当时的作用域中的变量。闭包不仅可以访问它自己的参数,它所在的环境中的变量,也可以访问它所在的环境的外部变量。
闭包通常是在嵌套函数中出现的(嵌套函数,理解为:在一个函数内部定义了另一个函数)。内层函数可以访问外层函数的变量,这就是闭包的作用所在。
闭包的一个重要特性是它可以记住并访问它被定义时的环境,即使它在当前环境之外被调用。这意味着,闭包可以长期保存它所需要的变量,即使这些变量在函数外部已经不存在了。
所以关于判断是否为闭包的条件:
(1)存在于嵌套关系的函数中。
(2)嵌套的内部函数引用了外部函数的变量。
(3)嵌套的外部函数会将内部函数名作为返回值返回。
栗子:
# 定义一个外层函数 outer_num,它接受一个参数 x
def outer_num(x):
# 定义一个内层函数 inner_num,它接受一个参数 y
def inner_num(y):
return x + y
return inner_num # 外层函数返回内层函数对象,不立即执行
answer = outer_num(5)
# 调用外层函数 outer_num,并传入参数 5
# 这时,外层函数的参数 x 被赋值为 5,并创建了一个闭包
# 闭包中包含了内层函数 inner_num 和其词法作用域中的变量 x
print(answer(10))
当外层函载的参数x被赋值为5的时候,就算创建完了一个简单的闭包。
最后一句中,内层函数的参数y被赋值为10的时候,内层函数就开始执行,并打印出结果。
二、装饰器
装饰器(Decorator)本质也是python的一种函数,用于修改或增强函数或类的行为。装饰器通过在不修改原始函数代码的情况下,给函数添加新的功能。
装饰器的工作原理是将一个函数作为参数传递给另一个函数,然后返回一个新的函数,这个新的函数在执行时会调用原始函数,并在原始函数的基础上添加额外的行为。
此外、在Python 中,装饰器的语法是以@开头。下面以一个简单的例子来说明下装饰器。
1.通过_不带参数的装饰器_用于运算
def num(func):
def inner(): # 定义一个内部函数返回给test函数
num1 = int(input("请输入第一个因数:"))
num2 = int(input("请输入第二个因数:"))
result = num1 * num2 # 计算乘积
func(result) # 调用函数并传入计算结果
return inner # 返回内部函数
@num # 使用装饰器num装饰test函数
def test(result): # test函数接收一个参数result
print('计算结果为:{}'.format(result)) # 把接受结果格式化
test() # 调用装饰后的函数,先执行num1和num2的输入,再执行test函数
打印结果:
2.通过_带参数的装饰器_区分成绩
对带参数的装饰器可理解为“加强装饰”,就是除了调用的函数带上参数,定义的内部函数也要都要带上参数。
def subject(func):
def mark(a, b, c): # 如果传入多个参数,就使用不定长参数*args
func(a, b, c)
return mark
@subject
def num(a, b, c):
print("语文:{a} 数学:{b} 英语:{c}".format(a=a, b=b, c=c))
num(66, 77, 88)
上面定义的mark()函数内部的执行语句func(),也要带上参数
3.通过_多个装饰器_登录应用
多个装饰器可以应用在同一个函数,调用的顺序是自上而下。
def user(buy):
def buyer():
account = input("请输入账号:")
if account == 'x':
buy()
else:
print("账户名错误")
return buyer
def key(buy):
def buyer():
password = input("请输入密码:")
if password == '12345':
buy()
else:
print("密码错误")
return buyer
@user
@key
def buy():
print("欢迎来到12306购票")
buy()
(敲黑板)这里的装饰器的应用顺序是:
1.最先应用 @key 装饰器,它返回一个闭包函数。
2.然后应用 @user 装饰器,它返回另一个闭包函数,该函数内部调用 @key 装饰器返回的函数。
所以,当buy()函数被调用时,实际上是这样的调用情况:
user (buyer) ——> key(buy)
与写闭包的顺序没半毛签关系
调用结果
4.通过_装饰器带返回值函数_判断质数
主要是中间要注意返回传入函数内部调用的参数
三、关于序列的常见内置函数
1、map函数
对可迭代对象中的每个元素所应用函数,并返回一个新的迭代器。
map函数语法如下:
map( function, iterable , ...)
在上述定义中,第一个参数 function 表示的是一个函数名,第二个参数 iterable 可以是序列或支持迭代的容器。当调用 map 函数时,iterable 中的每个元素都会调用function 函数,所有元素调用 function 函数返回的结果会保存到一个迭代的对象中。
栗子:
# lambda函数能接受任何数量参数,这里接受a,b两个,但是返回一个表达式,这里是b*c一种
a = map(lambda b, c: b*c, [1, 2], [4, 5])
# b*c的结果返回给map函数作为参数
print(list(a)) # 然后同过list(a)转成列表形式 打印
这里map 函数中传入的 function 函数带有两个参数:b,c。那么 map 函数需要传递两个序列。
2、zip函数
在Python中 ,zip()函数用于将两个或多个可迭代对象合并成一个元组的迭代器。zip()函数可以接受任意数量的可迭代对象作为参数,并返回一个元组的迭代器,其中每个元组包含输入可迭代对象中相应位置的元素。(蹩脚的理解:想象多个文件(列表)通过zip压缩到一个压缩包(迭代器)中)
zip函数语法如下:
zip(iterables...)
栗子:
# 创建两个列表
list1 = [1, 2, 3]
list2 = [' a', 'b', 'c']
# 使用 zip 函数将两个列表合并
combined = zip(list1, list2)
# 打印合并后的元组的列表形式
print(list(combined))
3、filter函数
在python中,filter函数会对指定序列执行过滤操作,就是从指定序列中筛选符合条件的元素。filter函数语法如下:
filter ( function, iterable )
上述语法中看出,filter函数接受两个参数:一个函数和一个序列。函数function用于测试序列中的每个元素是否满足条件,返回值可以为 True或False或None。序列iterable可以是任何序列,如列表、元组、字符串,或者任何可迭代对象,如:生成器表达式。
栗子:
# % 取余数的运算,让它恒等于0(==0),就是筛选处能被整除的数
# 反之不写==0,就是筛选会有余数的数,即:筛选出不能被整除的数
divide = lambda x: x % 4 == 0 # 能被4整除的数
result = filter(divide, [4, 8, 9])
print(list(result))
P.s.
周末愉快!加油!