zoukankan      html  css  js  c++  java
  • python 装饰器的坑

    今天研究了下装饰器,添加重试功能遇到了个坑,跟大家分享一下;

    代码如下:

     1 def re_try(maxtry):
     2     print locals()
     3     def wrapper(fn):
     4         print locals()
     5         def _wrapper(*args, **kwargs):
     6             print locals()
     7             while maxtry > 0:
     8                 try:
     9                     return fn(*args, **kwargs)
    10                 except Exception as e:
    11                     print e.message
    12                 maxtry -= 1
    13         return _wrapper
    14     return wrapper
    15 
    16 @re_try(4)
    17 def test(a, b):
    18     # return a+b
    19     if DEC == 2:
    20         return a+b
    21     else:
    22         raise WrapException
    23 
    24 def main():
    25     print test(3,5)
    26 
    27 if __name__ == '__main__':
    28     main()

    运行的结果如下:

    {'maxtry': 4}
    {'fn': <function test at 0x024B5170>}
    {'args': (3, 5), 'fn': <function test at 0x024B5170>, 'kwargs': {}}
    Traceback (most recent call last):
      File "D:myGit	est	estWrapp.py", line 58, in <module>
        main()
      File "D:myGit	est	estWrapp.py", line 55, in main
        print test(3,5)
      File "D:myGit	est	estWrapp.py", line 17, in _wrapper
        while maxtry > 0:
    UnboundLocalError: local variable 'maxtry' referenced before assignment

    按道理maxtry这个变量会一直存在再整个装饰器运行过程中,但是我们看到在第4行 和第6 行并没有看到该变量,本农百思不得七姐,于是就瞎调试,终于实现了功能。

     1 def re_try(max_try):
     2     print locals()
     3     def wrapper(func):
     4         print locals()
     5         @wraps(func)
     6         def _wrapper(*args, **kw):
     7             print locals()
     8             for i in xrange(max_try):
     9                 try:
    10                     res = func(*args, **kw)
    11                     if res is None:
    12                         continue
    13                     else:
    14                         return res 
    15                 except Exception as e:
    16                     print e.message
    17         return _wrapper
    18     return wrapper
    19 
    20 @re_try(4)
    21 def test(a, b):
    22     # return a+b
    23     if DEC == 2:
    24         return a+b
    25     else:
    26         raise WrapException
    27 
    28 def main():
    29     print test(3,5)
    30 
    31 if __name__ == '__main__':
    32     main()

    把while 循环改成了for循环,得到如下运行结果:

    {'max_try': 4}
    {'max_try': 4, 'func': <function test at 0x02613170>}
    {'args': (3, 5), 'kw': {}, 'func': <function test at 0x02613170>, 'max_try': 4}
    

    虽然目前还不知道为什么装饰器内部函数里面不能使用while,但是目前先记下来,日后觅得真理再来更新。

  • 相关阅读:
    表达式和计算的描述
    表达式和计算的描述
    递归算法浅谈
    编程基本功训练:流程图画法及练习
    【2012.1.24更新】不要再在网上搜索eclipse的汉化包了!
    VS2008下直接安装使用Boost库1.46.1版本号
    android关键组件service服务(一)
    U盘安装咱中国人自己的操作系统UbuntuKylin14.04LST(超具体原创图文教程)
    数据流图的画法
    匈牙利算法
  • 原文地址:https://www.cnblogs.com/huaizhi/p/8359724.html
Copyright © 2011-2022 走看看