GeorgeYang'Blog

my technology blog

python之闭包

阅读:173 创建时间:16-03-01 04:18:01 tags:python

常规的闭包:

 def make_adder(addend):
     def adder(augend):
         return augend + addend
     return adder

 p = make_adder(23)
 q = make_adder(44)

 print p(100)
 print q(100)

 运行结果:
 123
 144

其中p=make_addr(23)=addr(return augend+23)

如果调用p(100),结果是100+23,所以结果是23

和变量一起闭包:

 def f (name):
     count=[0] 
     def counter():
         count[0]+=1
         print 'Hello,',name,',',str(count[0])
     return counter

 hello = f('george')
 hello()
 hello()
 hello()
 输出结果:
 Hello, george , 1
 Hello, george , 2
 Hello, george , 3

因为hello是一个函数,连续调用,count[0]会+1,所以结果显示1,2,3

容易出错的使用方法:

 def g():
     ret = []
     for i in range(1,4):
         def h():
             return i*i
         ret.append(h)
     return ret

 gg = g()
 for i in range(0,3):
     print gg[i]()

 print '-----'

 def g2():
     ret = []
     for i in range(1,4):
         def h(j):
             return j*j
         ret.append(h)
     return ret

 gg = g2()
 for i in range(0,3):
     print gg[i](i)

 运行结果:
 9
 9
 9
 -----
 0
 1
 4

gg[i]都是函数,但上面的不需要参数,下面的需要参数,这种情况会出现一个覆盖问题,即i=1时g()=h(ii)和i=3时g()=h(ii)的结果是一样的,最后面的结果把前面的结果覆盖了,涉及到编译器的原理,读者有兴趣自行找资料阅读。

闭包和装饰器

 def makebold(fn):
     def wrapped():
         return "<b>" + fn() + "</b>"
     return wrapped

 def makeitalic(fn):
     def wrapped():
         return "<i>" + fn() + "</i>"
     return wrapped

 @makebold
 @makeitalic
 def hello():
     return "hello world"

 print hello() 
 运行结果:
 <b><i>hello world</i></b>

python装饰器的写法,装饰器的参数是一个函数或类,专门对类或函数进行加工处理。

python里的高级功能包括装饰器,生成器,列表推到,闭包,匿名函数等,使用它们让你的项目开发得到事半功倍的效果!