闭包:
函数内的属性,都是有生命周期的,都是在函数执行期间,函数执行完,就会被回收。
但可以通过闭包,将函数内的属性给保留下来,除非通过 del 删除掉,否则就是存在的。
内部函数对外部函数作用域(肚子里的东西)里变量的引用
def func(): # 外部函数
print("this is function")
def func1(): # 内部函数
print("this is function1")
func()
#输出
# this is function
若我想用func1,该怎么办呢?将func1()返回就可以用了啊
def func(): # 外部函数
print("this is function")
def func1(): # 内部函数
print("this is function1")
return func1
var = func() # 这时候return回来func1
var() # var == func1,var()==func1()
#输出
#this is function
#this is function1
# 一个真正意义上闭包的例子:函数层面的
# 内部函数对外部函数作用域里 *变量* 的引用(仔细理解)
def func(): # 外部函数
a = 1 # 外部函数作用域里的变量
print("this is function")
def func1(num): # 内部函数
print("this is function1")
print(num + a) # 将外部a的保下来。
通过return func1函数保下来
# (内部函数对外部函数作用域里 *变量* 的引用)
return func1 # 返回func1的函数名
var = func() # 这时候return回来func1
var(3) # var == func1,var()==func1()
# 输出
# this is function
# this is function1
# 4
但是此时a是在var里面的,若def val,那么此时a才会被真正意义的删除。
(看下面的例子),我们会发现obj其实是没有被删除的,obj[0] 仍然在叠加的状态。
mylist = [1, 2, 3, 4]
def func(obj):
print('func', obj)
def func1():
obj[0] += 1
print("func1", obj)
return func1
var = func(mylist)
var()
var()
var()
# 输出
#func [1, 2, 3, 4]
#func1 [2, 2, 3, 4]
#func1 [3, 2, 3, 4]
#func1 [4, 2, 3, 4]
闭包的意义:闭包是func(),闭包函数func1()
闭包内的闭包函数func1私有化了变量,完成了数据的封装,类似于面向对象。
装饰器存在的意义:不影响原有函数的功能,而且还可以添加新的功能。
场景:对不可修改的第三方API进行添加新功能。
# 装饰器 基于闭包
def func1(func): # 闭包函数的参数是外部闭包函数的参数,func是被装饰的函数对象, func是形参函数!
def func2():
print("aaaabbbb")
return func() # 返回了外部函数接收的参数被装饰函数的调用
return func2
# return func 返回了函数名
# return func() 返回的是一个函数调用
@func1 # 相当于 myprint = func1(myprint),这就是装饰器的功能
def myprint():
print("你好,我是print")
myprint() # 由于被装饰了,所以此处执行的实际为func1(myprint)(),接收被装饰的函数作为参数,而且还要被继续调用一次
# 流程:
# @func1相当于myprint == func1(myprint) 得到func2,即myprint=func2
# 而myprint() = func2(),所以执行func2(), 然后得到print("aaaabbbb"),然后得到func(),
# 而func=myprint,所以func()=myprint(),打印出print("你好,我是print")
# myprint()==func2()+func()
# 而func==myprint,所以
# myprint()==func2()+myprint()
2.2 装饰器函数带参数:多一层包装来接收装饰器的参数
# 要求:
# 调用men()时候,print("好好上班。
你不可以生娃")
# 调用women()时候,print("好好上班。
你可以生娃")
# def men():
# print("好好上班。
")
# def women():
# print("好好上班。
")
def func1(func,sex):
def func2():
if sex == "men":
print("你不可以生娃")
if sex == "women":
print("你可以生娃")
return func()
return func2
@func1(sex='men')
def men():
print("好好上班。
"
)
@func1(sex='women') # 但是这样会报错,所以其实还需要一个外层函数
def women():
print("好好上班。
"
)
men() # func1(men)()
# 报错
@func1(sex='men')
TypeError: func1() missing 1 required positional argument: 'func'
但是这样会报错,所以其实还需要一个外层函数,如下:
def func0(sex):
def func1(func):
def func2():
if sex == "men":
print("你不可以生娃")
if sex == "women":
print("你可以生娃")
return func()
return func2
return func1
# 带参装饰器:func0(sex='men')()()
#1、func0(sex='men')——>func1
#2、func1()——>func2 # 用了第一个()
#3、func2()用第二个()——>func()==men()
@func0(sex='men')
def men():
print("好好上班。
"
)
@func0(sex='women') # 但是这样会报错,所以其实还需要一个外层函数
def women():
print("好好上班。
"
)
men() # men()相当于func0(sex='men')()()
women()
# 输出
你不可以生娃
好好上班。
你可以生娃
好好上班。
2.3 被装饰的函数带参数:只需要在最内部函数传入
# 求和:接收两个参数。
# 实现被装饰函数,接收两个参数,并return a+b的值,并希望a,b本身都+5,不允许在mysum中实现。
def func1(func):
def func2(x, y):
print(x, y)
x += 5
y += 5
# x = 'a'
# y = 'b'
# 最后会实现:1+2 = ab
return func(x, y)
return func2
@func1
def mysum(a, b):
print(a + b)
mysum(1, 2)
# 即得到 1+2 =13
# 1 2
# 13
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)