Python裝飾器(decorator)學習

G8bao7發表於2015-10-26


點選(此處)摺疊或開啟

  1. #!/usr/bin/env python
  2. #coding=utf8
  3. import sys

  4. def deco(func):
  5.     print("before %s() called on %s." % (func, sys._getframe().f_code.co_name))
  6.     func()
  7.     print("after %s() called on %s." % (func, sys._getframe().f_code.co_name))
  8.     return func

  9. def deco_at_one(func):
  10.     print("before %s() called on %s." % (func, sys._getframe().f_code.co_name))
  11.     func()
  12.     print("after %s() called on %s." % (func, sys._getframe().f_code.co_name))
  13.     return func

  14. def deco_at_inline_noparams(func):
  15.     def _deco_inline():
  16.     print("before %s() called on %s." % (func, sys._getframe().f_code.co_name))
  17.     res = func()
  18.     print("after %s() called on %s." % (func, sys._getframe().f_code.co_name))
  19.     return res
  20.     return _deco_inline

  21. def deco_at_inline_params_fix(func):
  22.     def _deco_inline_params_fix(a, b):
  23.     print("before %s() called on %s." % (func, sys._getframe().f_code.co_name))
  24.     res = func(a, b)
  25.     print("after %s() called on %s." % (func, sys._getframe().f_code.co_name))
  26.     return res
  27.     return _deco_inline_params_fix

  28. def deco_at_inline_params_unfix(func):
  29.     def _deco_at_inline_params_unfix(*args, **kwargs):
  30.     print("before %s() called on %s." % (func, sys._getframe().f_code.co_name))
  31.     res = func(*args, **kwargs)
  32.     print("after %s() called on %s." % (func, sys._getframe().f_code.co_name))
  33.     return res
  34.     return _deco_at_inline_params_unfix

  35. def deco_at_inline_params_unfix_withparams(dcargs):
  36.     def _deco_at_inline_params_unfix_wp(func):
  37.     def __deco_at_inline_params_unfix_wp(*args, **kwargs):
  38.      print("before %s() called on %s(%s)." % (func, sys._getframe().f_code.co_name, dcargs))
  39.      res = func(*args, **kwargs)
  40.      print("after %s() called on %s(%s)." % (func, sys._getframe().f_code.co_name, dcargs))
  41.      return res
  42.     return __deco_at_inline_params_unfix_wp
  43.     return _deco_at_inline_params_unfix_wp


  44. def deco_at_inline_params_unfix_wp_cls(dc_cls):
  45.     # dc_cls must implement static method function 'fn_sm_1' and 'fn_sm_2'
  46.     # see 'locker' module
  47.     def _deco_at_inline_params_unfix_wp_cls(func):
  48.     def __deco_at_inline_params_unfix_wp_cls(*args, **kwargs):
  49.      print("before %s() called on %s(%s)." % (func, sys._getframe().f_code.co_name, dc_cls))
  50.      dc_cls.fn_sm_1()
  51.      res = func(*args, **kwargs)
  52.      dc_cls.fn_sm_2()
  53.      print("after %s() called on %s." % (func, sys._getframe().f_code.co_name))
  54.      return res
  55.     return __deco_at_inline_params_unfix_wp_cls
  56.     return _deco_at_inline_params_unfix_wp_cls

  57. class Class_Deco():
  58.     def __init__(self):
  59.     print("INIT deco class." )

  60.     @staticmethod
  61.     def fn_sm_1():
  62.     print(" call %s." % (sys._getframe().f_code.co_name))
  63.     
  64.     @staticmethod
  65.     def fn_sm_2():
  66.     print(" call %s." % (sys._getframe().f_code.co_name))
  67.     
  68. '''
  69. -------------------------------------------------------------------------------------------------------------------
  70. '''
  71. def fn():
  72.     print("%s() called." % (sys._getframe().f_code.co_name))
  73.     return 'ok'

  74. def fn_deco():
  75.     print("%s() called." % (sys._getframe().f_code.co_name))
  76.     return 'ok'

  77. '''
  78. decorator function 'deco_at_one' called only one time before 'main'
  79. decorator function 'deco_at_one' not called when per time call 'fn_at_deco_one'
  80. '''
  81. @deco_at_one
  82. def fn_at_deco_one():
  83.     print("%s() called." % (sys._getframe().f_code.co_name))
  84.     return 'ok'

  85. '''
  86. decorator function 'deco_at_inline_noparams' called when per time call 'fn_at_deco_inline'
  87. '''
  88. @deco_at_inline_noparams
  89. def fn_at_deco_inline_noparams():
  90.     print("%s() called." % (sys._getframe().f_code.co_name))
  91.     return 'ok'

  92. '''
  93. params samed between '_deco_inline_params_fix' and 'fn_at_deco_inline'
  94. '''
  95. @deco_at_inline_params_fix
  96. def fn_at_deco_inline_params_fix(a,b):
  97.     print("%s() called." % (sys._getframe().f_code.co_name))
  98.     return a+ b

  99. '''
  100. 'deco_at_inline_params_unfix' any params
  101. '''
  102. @deco_at_inline_params_unfix
  103. def fn_at_deco_inline_params_unfix_2(a,b):
  104.     print("%s() called." % (sys._getframe().f_code.co_name))
  105.     return a+ b

  106. '''
  107. 'deco_at_inline_params_unfix' any params
  108. '''
  109. @deco_at_inline_params_unfix
  110. def fn_at_deco_inline_params_unfix_3(a,b,c):
  111.     print("%s() called." % (sys._getframe().f_code.co_name))
  112.     return a + b + c

  113. '''
  114. function 'deco_at_inline_params_unfix_withparams' can input params
  115. '''
  116. @deco_at_inline_params_unfix_withparams("wpa")
  117. def fn_at_deco_inline_params_unfix_wp_a(a,b,c):
  118.     print("%s() called." % (sys._getframe().f_code.co_name))
  119.     return a + b + c

  120. @deco_at_inline_params_unfix_withparams("wpb")
  121. def fn_at_deco_inline_params_unfix_wp_b(a,b,c):
  122.     print("%s() called." % (sys._getframe().f_code.co_name))
  123.     return a + b * c

  124. @deco_at_inline_params_unfix_wp_cls(Class_Deco)
  125. def fn_at_deco_inline_params_unfix_wp_cls():
  126.     print("%s() called." % (sys._getframe().f_code.co_name))
  127.     return 'ok'

  128. '''
  129. execute order by @deco_[1,2,3]
  130. @deco_1
  131. @deco_2
  132. @deco_3
  133. def fn():
  134.     pass

  135. '''
  136. @deco_at_inline_noparams
  137. @deco_at_inline_params_unfix_withparams("wpc")
  138. @deco_at_inline_params_unfix_wp_cls(Class_Deco)
  139. def fn_at_deco_inline_mix():
  140.     print("%s() called." % (sys._getframe().f_code.co_name))
  141.     return 'ok'

  142. if __name__ == '__main__':
  143.     lin = " - " * 30

  144.     print lin
  145.     fna = fn()

  146.     print lin
  147.     fnb = deco(fn_deco)

  148.     print lin
  149.     fnc = fn_at_deco_one()
  150.     fnc = fn_at_deco_one()

  151.     print lin
  152.     fnd = fn_at_deco_inline_noparams()
  153.     fnd = fn_at_deco_inline_noparams()

  154.     print lin
  155.     a=2
  156.     b=3
  157.     fne = fn_at_deco_inline_params_fix(a,b)
  158.     print a,b,fne

  159.     a=12
  160.     b=32
  161.     fne = fn_at_deco_inline_params_fix(a,b)
  162.     print a,b,fne

  163.     print lin
  164.     a=2
  165.     b=3
  166.     fnf = fn_at_deco_inline_params_unfix_2(a,b)
  167.     print a,b,fnf

  168.     a=2
  169.     b=3
  170.     c=5
  171.     fnf = fn_at_deco_inline_params_unfix_3(a,b,c)
  172.     print a,b,c,fnf

  173.     print lin
  174.     fng = fn_at_deco_inline_params_unfix_wp_a(a,b,c)
  175.     print a,b,c,fng
  176.     fng = fn_at_deco_inline_params_unfix_wp_b(a,b,c)
  177.     print a,b,c,fng

  178.     print lin
  179.     fng = fn_at_deco_inline_params_unfix_wp_cls()

  180.     print lin
  181.     fnh = fn_at_deco_inline_mix()

  182.     exit(0)


參考 : http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

其他參考資料

1. Python裝飾器學習 http://blog.csdn.net/thy38/article/details/4471421

2. Python裝飾器與面向切面程式設計 http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

3. Python裝飾器的理解

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26250550/viewspace-1816298/,如需轉載,請註明出處,否則將追究法律責任。

相關文章