• 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,但是目前先记下来,日后觅得真理再来更新。

  • 相关阅读:
    整合了一个命令行程序的框架
    CentOS下mysql数据库data目录迁移和配置优化
    关于华硕主板的图像输出设置
    在jetson tx1下编译安装opencv3.2的一点小总结
    安装pydev 但是没有pydev工程选项
    关于PID控制的认识
    notebook( office + matlab)
    vmware 后台运行不能恢复
    将必应设置成chrome的默认搜索引擎
    centOS 7 apache 不能访问
  • 原文地址:https://www.cnblogs.com/huaizhi/p/8359724.html
Copyright © 2020-2023  润新知