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
bestkayle
V2EX  ›  Python

Python 中有没有办法先 return 再执行下面的代码

  •  
  •   bestkayle · 2017-08-22 09:26:48 +08:00 · 6961 次点击
    这是一个创建于 2410 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如有个情景是需要先返回'开始执行'然后进行执行任务。 或者 Python2 中有没有那种。。。异步的写法,类似 iOS 中的 block。

    26 条回复    2017-08-22 13:51:08 +08:00
    Zuckonit
        1
    Zuckonit  
       2017-08-22 09:35:40 +08:00
    yield
    bestkayle
        3
    bestkayle  
    OP
       2017-08-22 09:40:57 +08:00
    @ihonliu #2 这个刚看过了,说的最多的和一楼 @Zuckonit 一样是 yeild,还是感谢。
    fanhaipeng0403
        4
    fanhaipeng0403  
       2017-08-22 09:42:20 +08:00
    异步执行
    Immortal
        5
    Immortal  
       2017-08-22 09:44:59 +08:00
    "开始执行"这个应该是客户端可以直接处理
    服务端最终未开始执行(执行超时) 或 执行错误 再 return 给客户端才是正常处理方式?
    fanhaipeng0403
        6
    fanhaipeng0403  
       2017-08-22 09:46:45 +08:00
    celery apply_async
    bestkayle
        7
    bestkayle  
    OP
       2017-08-22 09:49:19 +08:00
    @fanhaipeng0403 #6 因为 celery 出了点问题刚把 celery 去掉了
    bestkayle
        8
    bestkayle  
    OP
       2017-08-22 09:50:43 +08:00
    @Immortal #5 我是怕有网络错误导致后端没有真正接收到。
    Immortal
        9
    Immortal  
       2017-08-22 10:08:05 +08:00
    @bestkayle 客户端应该做超时处理 多久未处理完(未收到服务端完成通知)算超时
    siloong
        10
    siloong  
       2017-08-22 10:17:31 +08:00
    第一反应也是 yield...
    inmyfree
        11
    inmyfree  
       2017-08-22 11:06:08 +08:00
    可以这样处理
    把要执行的任务模块化,先添加到任务列表,然后返回

    另起一个定时器或者守护线程类的,间隔 N 秒查询任务列表,有任务就执行,没有就完了
    est
        12
    est  
       2017-08-22 11:08:09 +08:00
    >>> def a():
    >>> try: return 1
    >>> except: pass
    >>> finally: print 'haha'
    >>>

    >>> a()
    haha
    1
    WildCat
        13
    WildCat  
       2017-08-22 11:11:03 +08:00
    yield/async await
    bestkayle
        14
    bestkayle  
    OP
       2017-08-22 11:14:27 +08:00
    @inmyfree #11 恩,改成任务队列的形式了。
    bestkayle
        15
    bestkayle  
    OP
       2017-08-22 11:14:54 +08:00
    @est #12 finally 会在 return 之前执行的,还是会阻塞。
    Immortal
        16
    Immortal  
       2017-08-22 11:39:15 +08:00
    @bestkayle 不清楚你做的是 web 还是什么业务 任务队列没法准备的把每个任务状态返回给客户端吧?比如有 1,2,3 个任务在队列里,其中 2 处理失败, 怎么告诉发布 2 任务的客户端失败这个信息?如果做 tcp 业务那是没问题
    est
        17
    est  
       2017-08-22 11:42:08 +08:00
    @bestkayle 你是想在 web 里先返回再处理一些额外的事儿?

    办法也是有的。真的先返回后执行了。
    bestkayle
        18
    bestkayle  
    OP
       2017-08-22 11:45:45 +08:00
    @Immortal #16 原来是有个进程在一直等待获取任务,重启的时候直接执行任务,现在改成了重启的时候也扔到任务队列里面去,加个重启的标签以便识别。
    est
        19
    est  
       2017-08-22 11:57:30 +08:00
    @bestkayle

    https://www.python.org/dev/peps/pep-0333/#specification-details

    If the iterable returned by the application has a close() method, the server or gateway must call that method upon completion of the current request, whether the request was completed normally, or terminated early due to an error (this is to support resource release by the application). This protocol is intended to complement PEP 325's generator support, and other common iterables with close() methods.
    goodryb
        20
    goodryb  
       2017-08-22 11:58:44 +08:00
    为什么要返回开始执行后在跑任务,奇怪的逻辑

    我理解应该是提交任务后,这个动作就结束了,后台执行任务时应该写入状态值,前端查询状态值来确认是否开始执行
    bestkayle
        21
    bestkayle  
    OP
       2017-08-22 12:11:52 +08:00
    @goodryb #20 就是类似于这样
    def ex():
    foo()
    return 'success'
    foo()是执行任务,想让它不阻塞。
    goodryb
        22
    goodryb  
       2017-08-22 12:41:40 +08:00
    @bestkayle #21

    如果是我,应该会这样做

    def ex():
    set_status("run")
    foo()
    set_status("end")
    return 'success'
    ericls
        23
    ericls  
       2017-08-22 12:59:09 +08:00 via iPhone
    楼主想解决 wsgi 返回 response 以后的操作?
    xieranmaya
        24
    xieranmaya  
       2017-08-22 13:05:11 +08:00 via Android
    tryfinally
    bestkayle
        25
    bestkayle  
    OP
       2017-08-22 13:30:38 +08:00
    @ericls #23 也没这么复杂,只是想让前面的任务代码不阻塞就行了。
    mansur
        26
    mansur  
       2017-08-22 13:51:08 +08:00
    服务器端接收请求后生成个随机码,连同待处理的数据一块发给 redis 队列,然后把随机码返回给客户端。另外起一个后台进程一直处理这个 redies 队列的消息,处理好了存库。客户端接收到随机码后带着这个随机码向服务器端请求处理结果,如果没有结果就循环重试,用 ajax 实现即可。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3670 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 117ms · UTC 00:12 · PVG 08:12 · LAX 17:12 · JFK 20:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.