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

posted @ 2018-03-22 12:09  奋斗的小虫子  阅读(128)  评论(0编辑  收藏  举报