python 系列(7) 装饰器

Posted on Posted in python

### 全局变量和局部变量

> eg1

  1. a_string = 'This is global varable'  
  2. def func():  
  3.     a = 1  
  4.     print "locals:" , locals() #局部变量  
  5.   
  6. print "globals:", globals() #生成字典,内容是一些全局的变量  
  7.   
  8. func()  
  9. # 输出  
  10. ''' 
  11. globals: {'__builtins__': <module '__builtin__' (built-in)>, '__file__': 't.py', 'a_string': 'This is global varable', 'func': <function func at 0x7fc99e134c80>, '__name__': '__main__', '__package__': None, '__doc__': '\ndef func():\n\tprint 101\n\treturn 100\n\nprint func()\n'} 
  12. locals: {'a': 1} 
  13. '''  

> eg2

  1. a_string = 'This is global varable'  
  2. def func():  
  3.         print a_string  
  4.   
  5. func() # 会输出上面的字符串,python先在局部变量里找,如果找不到,就去全局变量里找  

> eg3

  1. def func():  
  2.     a = 100  
  3. func()  
  4. print a #全局变量调用不了局部变量  

### 嵌套函数

  1. def outer():  
  2.         def inner():  
  3.                 print 'inner'  
  4.         return inner #这里没有括号  
  5.   
  6. func = outer() #函数坐变量  
  7. print func  
  8. func()  

### 闭包

1. 内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。
2. 一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包。

> 特点

1. 闭包私有化了变量,原来需要类对象完成的工作,闭包也可以完成
2. 闭包消耗内存
3. python中,使用闭包的一个场景,就是装饰器,也叫语法糖@

> eg1

  1. def outer(): # 只有outer运行的时候x才存在  
  2.     x = 1 # x是outer中的局部变量  
  3.     def inner():  
  4.         print x # 去上一层找x  
  5.     return inner # inner函数可以被outer返回  
  6.   
  7. func = outer() # inner储存在func变量当中  
  8. print func.func_closure # 获得inner函数的外套函数的命名空间  
  9. func()  
  10. # 当outer调用的时候就产生了一个闭包inner,并且该闭包含有变量x  
  11. # 输出  
  12. ''' 
  13. (<cell at 0x7fccb9d37b08: int object at 0x16ab168>,) 
  14. 1 
  15. '''  

> eg2

  1. # 定义一个函数  
  2. def func1(num):  
  3.         print "func1:", num  
  4.         # 这个函数内部继续定义一个函数,这个函数就是闭包  
  5.         def func2(num1):  
  6.                 print 'func2:' ,num1  
  7.                 return num + num1  
  8.         # 返回一个函数  
  9.         return func2 # 这个函数对象也可以成为函数实例  
  10. res = func1(20)  
  11. # 第一次调用的时候,创建了一个函数对象,而且保存下了参数值  
  12. # 函数内部的参数存货时间只存在函数调用的时候  
  13. # 通过闭包,把外层函数作用域里的变量保存到res这个函数对象中  
  14. # 在之后运行res这个函数对象的时候,num还是存在的  
  15. print res(30)  

> eg3

  1. def foo():  
  2.     m = 0  
  3.     def foo1():  
  4.         m = 1  
  5.         print m # 输出1,第二输出  
  6.     print m # 输入0,执行的时候,第一输出  
  7.     foo1()  
  8.     print m # 输出0,第三输出  
  9.   
  10. foo() # 输出 0 1 0  

> eg4,一个错误例子

  1. # 错误例子  
  2. def foo():  
  3.         a = 1  
  4.         def bar():  
  5.                 # 这里的a,没有定义,会报错  
  6.                 a = a + 1  
  7.                 return a  
  8.         return bar  
  9. c = foo()  
  10. print c()  

### 装饰器

在不动用函数源代码的情况下,增加新功能

> 模拟装饰器

  1. import time  
  2. def dec(fun):  
  3.         start = time.time()  
  4.         fun()  
  5.         runtime = time.time() - start  
  6.         print runtime  
  7. def a_func():  
  8.         for i in range(1000000):  
  9.                 pass  
  10.         print "abc"  
  11. dec(a_func)  

> 使用语法糖@装饰器

  1. import time  
  2. def dec(fun):  
  3.         def wrapper(): #产生一个闭包  
  4.                 start = time.time()  
  5.                 fun() # 形参传进来  
  6.                 runtime = time.time() - start  
  7.                 print runtime  
  8.         return wrapper # 返回内部这个作用函数  
  9.   
  10. @dec # 语法糖@,把a_func做为参数传给dec  
  11. def a_func():  
  12.         for i in range(1000000):  
  13.                 pass  
  14.         print "abc"  
  15. a_func()  

> 目标函数带参数的装饰器

  1. import time  
  2. def dec(fun):  
  3.     def wrapper(name): # 带了参数  
  4.         start = time.time()  
  5.         fun(name) # 带了参数  
  6.         runtime = time.time() - start     
  7.         print runtime  
  8.     return wrapper  
  9.   
  10. @dec  
  11. def a_func(name): # 带了参数  
  12.     for i in range(1000000):  
  13.         pass  
  14.     print "abc",name  
  15. a_func(" U name ")  

> 目标函数不固定参数的装饰器

  1. import time  
  2. def dec(fun):  
  3.     def wrapper(*args, **kwargs):  
  4.         start = time.time()  
  5.         fun(*args, **kwargs)  
  6.         runtime = time.time() - start     
  7.         print runtime  
  8.     return wrapper  
  9.   
  10. @dec  
  11. def a_func(name):  
  12.     for i in range(1000000):  
  13.         pass  
  14.     print "abc",name  
  15.   
  16. @dec  
  17. def a_func2(user,name):  
  18.     for i in range(1000000):  
  19.         pass  
  20.     print user + 'aaaaaaaaaa' + name  
  21.   
  22. a_func(" U name ")  
  23. a_func2('st','roro')  

> 目标函数每次调用重复执行指定的次数,装饰器

  1. import time  
  2. def dec(max): # max 为次数  
  3.     def _dec(fun):  
  4.         def wrapper(*args,**kwargs): # 嵌套两个函数  
  5.             start = time.time()  
  6.             for i in xrange(max):  
  7.                 fun(*args,**kwargs)  
  8.             runtime =  time.time() - start  
  9.             print runtime  
  10.         return wrapper # 返回第一层的函数  
  11.     return _dec # 返回第二层的函数  
  12.       
  13. @dec(5) # 装饰器需要传一个参数  
  14. def a_func(name):  
  15.     for i in range(1000000):  
  16.         pass  
  17.     print "abc",name  
  18.   
  19. a_func(" U name ")  
» 转载请注明来源:呢喃 » python 系列(7) 装饰器

One thought on “python 系列(7) 装饰器

  1. Google Chrome 39.0.2171.95 Google Chrome 39.0.2171.95 Windows 8.1 Windows 8.1
    Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36

    Thanks for finally writing about >python 系列(7) 装饰器 – 若我若鱼 | liuhonghe.me <Loved it!

Leave a Reply

Your email address will not be published. Required fields are marked *

18 − seventeen =