python装饰器与闭包的区别,学好python拿高薪系列一
python装饰器与闭包的区别,学好python拿高薪系列一def func():#外部函数6、闭包应用场景:作用域;装饰器(语法糖@)3、外部函数加上内部函数组成了闭包,内部函数即为闭包函数,4、闭包内的闭包函数私有化了函数(外部)中的变量,完成了数据的封装,类似于面向对象5、使得在函数周期中快要死亡的变量存活下来
小伙伴们大家好,在上一期我们分享了python面向对象的基础内容,那么在分享面向对象进阶部分之前,我想先分享一下闭包与装饰器的内容,因为这部分内容大部分初学者都觉着晦涩难懂。
闭包通俗一点来说,python中的闭包就是为了使得在函数周期中将要死亡的变量存活下来。注意点如下:
1、内部函数对外部函数作用域内变量的引用
2、函数内的属性,都有生命周期,都是在函数执行期间的
3、外部函数加上内部函数组成了闭包,内部函数即为闭包函数,
4、闭包内的闭包函数私有化了函数(外部)中的变量,完成了数据的封装,类似于面向对象
5、使得在函数周期中快要死亡的变量存活下来
6、闭包应用场景:作用域;装饰器(语法糖@)
一、作用域问题def func():#外部函数
print("this is func.")
def func1():#内部函数
print("this is func1.")
func()
func1()#这个函数在func函数调用的时候才创建
我们可以发现,外部函数func调用后,内部函数还是无法执行,
这是因为函数是有生命周期的,当func函数执行完毕后,func1函数也消亡了
def f():
a=1
f()
print(a)#此时,a显示未定义,解决方法就是用return语句
同理,对于func1内部函数如果想要执行,就可以使用return函数
将内部函数返回,并用变量接收,防止外部函数执行完毕后死掉
def func():
print("this is func.")
def func1():
print("this is func1.")
return func1
f=func()
f()#此时就可以执行内部函数了
二、变量问题def func():
a=1#外部函数作用域里的变量
print("this is func.")
def func1(num):
print("this is func1.")
print(num a)#让外部变量活下来
return func1
f=func()
f(3)
此时之所以能正常输出num a的值是因为,a保存在了func1()中
并且返回给了f变量,存活了下来
这就是闭包的意义:让本该在函数执行结束后死掉的变量通过载体活下来
del f #此时载体被删除后,a变量也就死了
三、闭包实例练习li=[1 2 3 4 5]
def func(obj):
print("func" obj)
def func1():
obj[0] =1
print("func1" obj)
return func1
f=func(li)
f()
f()
f()
装饰器:基于闭包实现1、存在意义:不影响原有函数的功能,而且添加新的功能
2、应用场景:
例如拿到了一个第三方API 好用但不允许修改,那么就可以使用
装饰器添加新的功能
3、在执行函数之前先执行装饰器
4、 @func1
def myprint():
myprint()==func2() func()
而myprint()被当做一个参数扔到装饰器中去
所以myprint()==func2() myprint()
5、被装饰的函数带参数,在闭包函数最内层直接接收
一、装饰器案例def func1(func):#闭包函数中外部函数的参数是被装饰的函数对象
def func2():
print("aaabbb")
return func()#返回外部函数的参数的调用,该函数是被装饰函数
return func2
return func#返回一个函数对象(地址)
return func()返回一个函数调用
@func1==func1(myprint)() 接受被装饰的函数并进行函数调用
@func1
def myprint():#myprint()被当作一个参数扔到func1装饰函数中
print("你好,myprint")
myprint()#在执行此函数前先执行func1装饰函数
这个装饰器执行过程就相当于
1、func1(myprint)()->return func2()
2、调用func2()-->print("aaabbb")
3、调用func()->func()即为myprint()
4、print("你好,我是print")
二、装饰器练习def args_func(sex):
def func1(func):
def func2():
if sex=="man":
print("不能生孩子")
else:
print("能生孩子")
return func()
return func2
return func1
@args_func(sex='man')
def man():
print("好好上班")
@args_func(sex='woman')
def woman():
print("好好上班")
woman()
man()
#闭包中的内部函数可以直接接受被装饰函数的参数
def func1(func):
def func2(x y):#对应位置x y接收被装饰函数的参数
print(x y)
x =5
y =5
return func(x y)#此时调用被装饰函数mysum(a b) 故要传入参数
return func2
@func1
def mysum(a b):
print(a b)
mysum(1 2)
好了今天的分享就到此结束了,在下一期将分享的是python面向对象的进阶部分。欢迎持续关注小编相互交流!