V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
windcode
V2EX  ›  Python

使用 try-except 包含网络请求语句,有没有更好的写法?

  •  
  •   windcode ·
    elliotxx · 2018-05-04 15:02:24 +08:00 · 2580 次点击
    这是一个创建于 2155 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,想保证网络请求一定能获得返回的结果,目前常用写法见下。如果请求语句没报错,就跳出循环,否则反复发送网络请求,直到成功。

    有没有更优雅的写法?

    样例代码:

    import requests
    
    while True:
        try:
            response = requests.get('http://www.xxxxxxxxx.com')
            break
        except Exception,e:
            print str(e)
    
    print response.status_code
    
    11 条回复    2018-05-04 16:26:19 +08:00
    lihongjie0209
        1
    lihongjie0209  
       2018-05-04 15:04:53 +08:00   ❤️ 1
    对面服务器挂了, 你这个就是死循环了, 好一点的办法是捕捉异常之后把失败的 url 放到失败队列中, 找个机会重试
    windcode
        2
    windcode  
    OP
       2018-05-04 15:11:35 +08:00
    @lihongjie0209 这当然是个好的办法,但在这里只想探索下这段代码有没有好的写法
    glacer
        3
    glacer  
       2018-05-04 15:19:33 +08:00
    装饰器加设置重试

    ```python
    def request_retry(times):
    def decorator(func):
    def wrapper(*args, **kwargs):
    while times > 0:
    try:
    return func(*args, **kwargs)
    # 各种异常捕获
    except RequestException as e:
    times -= 1
    else:
    raise HTTPRequestFailedException() # 自定义的异常
    return wrapper
    return decorator
    ```
    lihongjie0209
        4
    lihongjie0209  
       2018-05-04 15:22:20 +08:00
    @windcode 没有, 网络异常是必然的, 可预见的, 必须加异常处理, 至于怎么处理看业务需求
    windcode
        5
    windcode  
    OP
       2018-05-04 15:23:12 +08:00
    @glacer 可以的,装饰器写法 get 了
    glacer
        6
    glacer  
       2018-05-04 15:28:26 +08:00
    @windcode 回复不支持 markdown 真是蛋疼,缩进都没了,上面的 else 是 while...else,不是 try...except...else。
    Hopetree
        7
    Hopetree  
       2018-05-04 15:40:00 +08:00
    timeout 设置一波啊,你用 try 不就想在制定时间得到响应吗,不然用 try 干嘛,要是请求失败要等好久的,所以肯定要设置超时啊
    windcode
        8
    windcode  
    OP
       2018-05-04 15:42:23 +08:00
    @Hopetree 工程里 timeout 设置了,最大请求次数也设置了,跑起来效率和准确度还行,只是觉得这样一坨代码写的有点丑(笑哭
    windcode
        9
    windcode  
    OP
       2018-05-04 15:42:49 +08:00
    @glacer 了然~ 代码看懂了
    hcymk2
        10
    hcymk2  
       2018-05-04 15:51:08 +08:00
    可以试下递归。
    zhaoshengzhi
        11
    zhaoshengzhi  
       2018-05-04 16:26:19 +08:00
    贴一串以前的,用 auto_retry 自动重试,用 time_limit 设置时间限制,也可以组合同时使用


    import traceback
    import json
    import subprocess

    import eventlet

    eventlet.monkey_patch()

    RETRY_COUNT = 10

    TIMEOUT = 10


    def time_limit(func, *args, **kwargs):
    trace = None
    for _ in range(RETRY_COUNT):
    try:
    with eventlet.Timeout(TIMEOUT):
    return func(*args, **kwargs)
    except eventlet.timeout.Timeout, e:
    trace = format_traceback()
    except:
    trace = format_traceback()

    ignore_exception = kwargs.get('ignore_exception')
    if not ignore_exception:
    raise Exception(
    "max retry count=%d, func=%s, argv=%s, trace=%s" % (RETRY_COUNT, func.__name__, (args, kwargs), trace))


    def auto_retry(func, *args, **kwargs):
    trace = None
    for _ in range(RETRY_COUNT):
    try:
    return func(*args, **kwargs)
    except:
    trace = format_traceback()

    ignore_exception = kwargs.get('ignore_exception')
    if not ignore_exception:
    raise Exception(
    "max retry count=%d, func=%s, argv=%s, trace=%s" % (RETRY_COUNT, func.__name__, (args, kwargs), trace))


    def format_traceback():
    trace = traceback.format_exc()
    return json.dumps(trace, ensure_ascii=False)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5232 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:25 · PVG 09:25 · LAX 18:25 · JFK 21:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.