Python闭包和装饰器

来自linux中国网wiki
Evan讨论 | 贡献2022年2月23日 (三) 08:21的版本 →‎装饰器
跳到导航 跳到搜索

要先理解闭包,再理解装饰器

闭包

 什么是闭包

#定义一个函数
def test(number):

    #在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
    def test_in(number_in):
        print("in test_in 函数, number_in is %d"%number_in)
        return number+number_in
    #其实这里返回的就是闭包的结果
    return test_in


#给test函数赋值,这个20就是给参数number
这时候 ret 指向是test_in 也就是里面的那个function
ret = test(20)

#注意这里的100其实给参数number_in
print(ret(100))

#注意这里的200其实给参数number_in
print(ret(200))
运行结果:


in test_in 函数, number_in is 100
120

in test_in 函数, number_in is 200
220

cat 1.py 
"""
--1--
--3--
*************************
--2--
200

"""
def test(number):

    print("--1--")

    def test_in():
        print("--2--")
        print(number+100)

    print("--3--")
    return test_in
ret = test(100)
print("*"*25)
ret()


  
def test(number):

    print("--1--")

    def test_in():
        print("--2--")
        print(number+100)

    print("--3--")
    return test_in

test(100)
#ret = test(100)

"""
--1--
--3--
"""

def test(number):

    print("--1--")

    def test_in(number2):
        print("--2--")
        print(number+number2)

    print("--3--")
    return test_in


ret = test(100)
print("-"*30)
ret(1)
ret(100)
ret(200)

"""
 python3  01-闭包/01-闭包1.py 
--1--
--3--
------------------------------
--2--
101
--2--
200
--2--
300

"""

装饰器


现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:

把@log放到now()函数的定义处,相当于执行了语句:
now = log(now)



"""
---正在验证权限----
---f1---
"""
def w1(func):
    def inner():
        print("---正在验证权限----")
        func()
    return inner

def f1():
    print("---f1---")

def f2():
    print("---f2---")

#innerFunc = w1(f1)
#innerFunc()

#这是的f1 其实是inner了  只有func才是原来的f1
f1 = w1(f1)  
f1()

运行流程如下  一开始是 f1 = w1(f1)   先算右边的 w1(f1)  这时候 func指向def f1 ,而左边的f1 为def inner  所以 运行最后一行 f1()时  就是先运行 inner fun 打印 ---正在验证权限----,第二步 func() 也就是原来的f1 fun 所以打印---f1---

不明请看下面的wrapp原理图片
<2019-03-28 四>

****************************分隔线**********************************************************

#定义函数:完成包裹数据
"""
----1---
----2---
----3---
<b><i>hello world-3</i></b>

"""
def makeBold(fn):
    def wrapped():
        print("----1---")
        return "<b>" + fn() + "</b>"
     return wrapped

#定义函数:完成包裹数据
def makeItalic(fn):
    def wrapped():
        print("----2---")
        return "<i>" + fn() + "</i>"
    return wrapped

@makeBold
@makeItalic
def test3():
    print("----3---")
    return "hello world-3"

ret = test3()
print(ret)


50px


50px

参考

如何理解Python装饰器?


深入浅出理解python 装饰器


Python装饰器学习(九步入门)


https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000

Python 的闭包和装饰器

https://segmentfault.com/a/1190000004461404

http://www.cnblogs.com/ChrisChen3121/p/3208119.html

https://www.zhihu.com/question/31792789

http://www.cnblogs.com/zhiyong-ITNote/p/7384955.html