首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测作为子例程调用的python协程

检测作为子例程调用的python协程
EN

Stack Overflow用户
提问于 2015-08-17 22:46:08
回答 1查看 204关注 0票数 1

假设我有一堆协程。应该使用yield from调用这些协程。我如何发现我犯了一个错误,并像子例程一样直接调用协程?

下面是一个示例代码:

代码语言:javascript
复制
import asyncio

@asyncio.coroutine
def A(msg):
    print(msg)
    yield from asyncio.sleep(1)

@asyncio.coroutine
def B():
    while True :
        yield from A('1')
        A('2')
        yield from A('3')

loop = asyncio.get_event_loop()
loop.run_until_complete(B())

和输出:

代码语言:javascript
复制
1
3
1
3
1
3
...

像子例程一样调用协程什么也不做,但不会引发异常或阻塞事件循环,因此失败模式非常安静。

EN

回答 1

Stack Overflow用户

发布于 2015-08-18 08:53:09

我在您的代码中添加了一个check_iterator函数。如果你用这个函数装饰你的协程,如果你的协程被直接调用并且不能使用__iter__访问,它将打印出信息。不过,这可能会有一些性能上的下降。

代码语言:javascript
复制
import asyncio
import functools

class IterWrap(object):
    def __init__(self, f, *args, **kwds):
        self.iterated = False
        self.info = [f, args, kwds]
        self.f = f(*args, **kwds)

    def __iter__(self):
        self.iterated = True
        return iter(self.f)

    def __del__(self):
        if not self.iterated:
            print("Did not yield: %s" % self.info)

def check_iterator(f):
    @functools.wraps(f)
    def wrapper(*args, **kwds):
        return IterWrap(f, *args, **kwds)
    return wrapper

@check_iterator
@asyncio.coroutine
def A(msg):
    print(msg)
    yield from asyncio.sleep(1)

@asyncio.coroutine
def B():
    while True :
        yield from A('1')
        A('2')
        yield from A('3')

loop = asyncio.get_event_loop()
loop.run_until_complete(B())

在Python 3.4上运行此命令的结果如下:

代码语言:javascript
复制
1
Did not yield: [<function A at 0xb6e3189c>, ('2',), {}]
3
1
Did not yield: [<function A at 0xb6e3189c>, ('2',), {}]
3
1
Did not yield: [<function A at 0xb6e3189c>, ('2',), {}]
3
1
Did not yield: [<function A at 0xb6e3189c>, ('2',), {}]
3
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32053361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档