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

代码如下:

 def re_try(maxtry):
print locals()
def wrapper(fn):
print locals()
def _wrapper(*args, **kwargs):
print locals()
while maxtry > 0:
try:
return fn(*args, **kwargs)
except Exception as e:
print e.message
maxtry -= 1
return _wrapper
return wrapper @re_try(4)
def test(a, b):
# return a+b
if DEC == 2:
return a+b
else:
raise WrapException def main():
print test(3,5) if __name__ == '__main__':
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\test\testWrapp.py", line 58, in <module>
main()
File "D:\myGit\test\testWrapp.py", line 55, in main
print test(3,5)
File "D:\myGit\test\testWrapp.py", line 17, in _wrapper
while maxtry > 0:
UnboundLocalError: local variable 'maxtry' referenced before assignment

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

 def re_try(max_try):
print locals()
def wrapper(func):
print locals()
@wraps(func)
def _wrapper(*args, **kw):
print locals()
for i in xrange(max_try):
try:
res = func(*args, **kw)
if res is None:
continue
else:
return res
except Exception as e:
print e.message
return _wrapper
return wrapper @re_try(4)
def test(a, b):
# return a+b
if DEC == 2:
return a+b
else:
raise WrapException def main():
print test(3,5) if __name__ == '__main__':
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,但是目前先记下来,日后觅得真理再来更新。

python 装饰器的坑的更多相关文章

  1. Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方案

    本文为霍格沃兹测试学院学员学习笔记. Python 装饰器简介 装饰器(Decorator)是 Python 非常实用的一个语法糖功能.装饰器本质是一种返回值也是函数的函数,可以称之为“函数的函数”. ...

  2. Python装饰器的调用过程

    在Python学习的过程中,装饰器是比较难理解的一个应用.本人也在学习期间也遇到很多坑,现将装饰器的基本调用过程总结一下. 首先,装饰器用到了“闭包”,而“闭包”是学习装饰器的基础,所以在讲装饰器之前 ...

  3. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  4. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  5. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  6. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  7. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  8. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  9. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

随机推荐

  1. 强大的性能监控pidstat

    前言 pidstat 可以监控单个任务.比如CPU.内存.IO.上下文切换.详细参考 man pidstat 安装 yum install sysstat 使用 1.监控所有活动进程 pidstat ...

  2. js变量var与let的区别

    1.作用域 通过var定义的变量,作用域是整个封闭函数,是全域的 .通过let定义的变量,作用域是在块级或是子块中. for (let i = 0; i < 10; i++) { // ... ...

  3. JavaSE---多线程---Callable、Future

    1.概述 1.1 JDK1.5后,Java提供了Callable接口,该接口提供一个call方法作为线程执行体,该call方法可以  有返回值.声明抛出异常: 因此,我们可以直接将Callable接口 ...

  4. JavaSE---多线程---线程的创建、启动

    1.概述 1.1 Java中使用Thread类表示线程:   所有的线程对象必须是Thread类 或 其子类的实例:   每条线程的作用:完成一定的任务:   Java中使用run方法来封装线程执行体 ...

  5. Android---OS

    一.概述 基于Linux的OS,内置JVM 二.发展史 二.系统架构

  6. qt学习 (五) 登陆界面之连接按钮

    登陆步骤是比对输入的账号密码与数据库中的表项目是否一致 一样,  跳出mainwidget对话框 不一样,跳出消息错误框 今天就是要进去, 因为进去以后是widget的窗口,所以把用来核对消息的数据库 ...

  7. Linux下github的使用

    在linux下搭建git环境 1.创建Github账号,https://github.com 2.Linux创建SSH密钥: ssh-keygen ##一直默认就可以了 3.将公钥加入到Github账 ...

  8. oracle中解决中文乱码问题

    中文乱码问题解决 1.查看服务器端编码 select userenv('language') from dual; 查到结果是: USERENV('LANGUAGE') --------------- ...

  9. ROS录制主题和放

    1.按照指定名称录制指定主题, 如录制主题为line_markers,名称为line_extraction的bag包. rosbag record -O line_extraction.bag /li ...

  10. Excel表格文本格式的数字和数字格式如何批量转换

    Excel表格文本格式的数字和数字格式如何批量转换 在使用Excel表格对数据求和时,只能对单元格内常规格式的数据进行计算,而不能对单元格中的文本格式的数据进行计算,特点就是在单元格的左上角有一个绿色 ...