• python基础之闭包,装饰器


    一:闭包

    闭包概念:

                  在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。

    个人理解就是:内部函数调用外部函数的变量,参数等,外部函数返回的是内部函数

     1 def set(number):
     2     print("---------外部函数输出-----------")
     3     def get():
     4         print("-------------内部函数----------")
     5         a = number+100
     6         print(a)
     7     return get
     8 
     9 >>> b = set(100)
    10 ---------外部函数输出-----------
    11 >>> b()
    12 -------------内部函数----------
    13 200

    上述例子就是一个闭包,b其实就是相当于是get()函数(或者说b就是指向get()),然后b()就相当于在调用get()函数。其实如果内部函数get()带有参数,那么可以b(参数)。

    二:装饰器

       例1:

    1 def test(fn):
    2     def test1():
    3         print('-----11------')
    4 
    5     return test1
    6 @test
    7 def fn():
    8     print('-----222-------')
    9 fn()

    运行结果:

    1 -----11------

    例2:

    1 def test(fn):
    2     def test1():
    3         print('-----11------')
    4         fn()
    5     return test1
    6 @test
    7 def fn():
    8     print('-----222-------')
    9 fn()

    运行结果:

    1 -----11------
    2 -----222-------

     个人理解装饰器:就是闭包写一个额外的功能,然后在不用在原基础代码中添加代码,其中靠@实现(也称语法糖)

    上述例子中:

    在fn()就函数上加上@test 就相当于执行以下三步:

    1:调用test()函数,

    2:把fn()函数当做参数传入test()函数中,然后返回test1()函数对象,

    3:然后调用test1()函数。

    注意:如果在test1()函数中 没用调用fn函数,那么结果只会输出test1()函数中的结果;如果调用,则会先返回test1()函数中的结果,然后再返回fn()函数中的。 

    例3:

     1 def makeBlod(fn):
     2     def wrapped():
     3         return "<b>"+fn()+"</b>"
     4     return wrapped
     5 
     6 >>> @makeBlod
     7 def test():
     8     return "xxx是一个大傻子"
     9 
    10 >>> test()
    11 '<b>xxx是一个大傻子</b>'

    注意:在闭包模式的内部函数中调用test()函数,没有必要非要写test()调用,只要和参数一致即可。

    3:有参数的函数使用装饰器

     1 def test(fn):
     2     def test1(a,b):
     3         print('-----11------')
     4         fn(a,b)
     5     return test1
     6 @test
     7 def fn(a,b):
     8     c = a + b
     9     print('-----222-------')
    10     print(c)
    11 fn(10,11)

    运行结果:

    1 -----11------
    2 -----222-------
    3 21

    注意:就是当调用的函数带有参数时,则需要在闭包中的内部函数带上参数,内部函数中调用的函数也需要带上参数

    3.1:当参数不定长时

    def test(fn):
        def test1(*args,**kwargs):
            print('-----11------')
            fn(*args,**kwargs)
        return test1
    @test
    def fn(a,b,c):
        print('-----222-------')
        d=a+b+c
        print(d)
    
    fn(5,6,7)

    运行结果:

    1 -----11------
    2 -----222-------
    3 18

    4:对带有返回值的函数进行装饰器装饰

     1 def test(fn):
     2     def test1():
     3         print('-----11------')
     4         xxx  = fn()
     5         return xxx
     6     return test1
     7 @test
     8 def fn():
     9     print('-----222-------')
    10     return '我是带有返回值的函数'
    11 
    12 a = fn()
    13 print(a)

    运行结果:

    -----11------
    -----222-------
    我是带有返回值的函数

    注意:对带有返回值的函数使用装饰器进行装饰的时候,需要在内部函数中调用的时候,用xxx接收,然后返回

    5:带有参数的装饰器

     1 def f_arg(arg):
     2     def test(fn):
     3         def test1():
     4             print('-----11------')
     5             fn()
     6         return test1
     7     d=arg+10
     8     print(d)
     9     return test
    10 @f_arg(10)
    11 def fn():
    12     print('-----222-------')
    13 fn()

    运行结果:

    1 20
    2 -----11------
    3 -----222-------

    理解:@f_arg(10)就是

           1:先执行f_arg(arg)函数,这个函数的return的结果就是test这个函数的引用

           2:@test

           3:使用@test对fn()函数进行装饰

    以上是个人理解,2018-03-22

  • 相关阅读:
    Talk the Talk
    2.1 使用eclipse4.4 搭建 maven简单结构项目。
    [LeetCode] Best Time to Buy and Sell Stock
    hdu4605Magic Ball Game 树状数组
    phoenixframe自己主动化平台在Linux环境下运行用例的说明
    数据存储值归档Archive
    BZOJ 1040 ZJOI2008 骑士 树形DP
    HDOJ 5357 Easy Sequence DP
    Autodesk 招聘Revit二次开发咨询顾问,与Autodesk全球团队紧密合作,提高职业生涯的好机会
    Codeforces Round #263 (Div. 1) A B C
  • 原文地址:https://www.cnblogs.com/qigege1104/p/8620437.html
Copyright © 2020-2023  润新知