[关闭]
@knight 2016-01-14T22:01:36.000000Z 字数 2339 阅读 2313

Python装饰器

python


1. 函数作用域LEGB

LEGB:L>E>G>B

判断一个学生是否及格。

  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. passline = 60
  4. def func(val):
  5. #passline = 90
  6. if val >= passline:
  7. print ("pass")
  8. else:
  9. print ("failed")
  10. def in_func():
  11. print (val)
  12. def Max(val1, val2):
  13. return max(val1,val2)
  14. func(89)

通过上面例子,了解函数作用域和LEGB规则

2. 闭包理解与使用

Closure: 内部函数中对enclosing作用域的变量进行引用。
函数实质与属性
1. 函数是一个对象
2. 函数执行完成后内部变量回收
3. 函数属性
4. 函数返回值

  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. passline = 60
  4. def func(val):
  5. #passline = 90
  6. print ('%x'%id(val))
  7. if val >= passline:
  8. print ("pass")
  9. else:
  10. print ("failed")
  11. def in_func():
  12. print (val)
  13. in_func()
  14. return in_func
  15. f = func(89)
  16. f()
  17. print (f.__closure__)

使用闭包

  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. passline = 60
  4. def func_150(val):
  5. passline = 90
  6. if val >= passline:
  7. print ('pass')
  8. else:
  9. print ('failed')
  10. def func_100(val):
  11. passline = 60
  12. if val >= passline:
  13. print ('pass')
  14. else:
  15. print('failed')
  16. def set_passline(passline):
  17. def cmp(val):
  18. if val >= passline:
  19. print('pass')
  20. else:
  21. print ('failed')
  22. return cmp
  23. f_100 = set_passline(60)
  24. print type(f_100)
  25. print (f_100.__closure__)
  26. f_100(89)
  27. f_100(59)
  28. f_150 = set_passline(90)
  29. f_150(89)

闭包作用
1. 封装
2. 代码复用

  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. def my_sum(*arg):
  4. # if len(arg) == 0:
  5. # return 0
  6. # for val in arg:
  7. # if not isinstance(val, int):
  8. # return 0
  9. return sum(arg)
  10. def my_average(*arg):
  11. # if len(arg) == 0:
  12. # return 0
  13. # for val in arg:
  14. # if not isinstance(val, int):
  15. # return 0
  16. return sum(arg)/len(arg)
  17. # 使用闭包完成
  18. def dec(func):
  19. def in_dec(*arg):
  20. if len(arg) == 0:
  21. return 0
  22. for val in arg:
  23. if not isinstance(val, int):
  24. return 0
  25. return func(*arg)
  26. return in_dec
  27. my_sum = dec(my_sum)
  28. my_average = dec(my_average)
  29. print (my_sum(1,2,3,4,5))
  30. print (my_sum(1,2,3,4,5, '6'))
  31. print (my_average(1,2,3,4,5))
  32. print (my_average())

3. 装饰器

  1. 装饰器用来装饰函数
  2. 返回一个函数对象
  3. 被装饰函数标识符指向返回的函数对象
  4. 语法糖 @deco
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. def dec(func):
  4. print ("call dec")
  5. def in_dec(*arg):
  6. if len(arg) == 0:
  7. return 0
  8. for val in arg:
  9. if not isinstance(val, int):
  10. return 0
  11. return func(*arg)
  12. return in_dec
  13. @dec
  14. def my_sum(*arg):
  15. # if len(arg) == 0:
  16. # return 0
  17. # for val in arg:
  18. # if not isinstance(val, int):
  19. # return 0
  20. return sum(arg)
  21. @dec
  22. def my_average(*arg):
  23. # if len(arg) == 0:
  24. # return 0
  25. # for val in arg:
  26. # if not isinstance(val, int):
  27. # return 0
  28. return sum(arg)/len(arg)
  29. print (my_sum(1,2,3,4,5))
  30. print (my_sum(1,2,3,4,5, '6'))
  31. print (my_average(1,2,3,4,5))
  32. print (my_average())

装饰器等价于闭包调用,使用语法糖可以隐式的调用。

call dec
call dec
15
0
3
0
  1. def deco(func):
  2. def in_deco(x,y):
  3. print ('in deco')
  4. func(x,y)
  5. print ('call deco')
  6. return in_deco
  7. # deco(bar) -> in_deco
  8. # bar = in_deco
  9. # bar() in_deco() bar()
  10. @deco
  11. def bar(x,y):
  12. print ('in bar', x+y)
  13. print (type(bar))
  14. bar(1,2)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注