python - 在 asyncio(和观察者模式)中链接协程

标签 python python-3.x python-asyncio

我无法理解协程是如何链接在一起的。在一个比 hello world 或 factorials 稍微简单的例子中,我想要一个循环,它持续监视文件修改时间,然后在文件被触摸时打印出时间:

#!/usr/bin/env python3
import os
import asyncio

@asyncio.coroutine
def pathmonitor(path):
    modtime = os.path.getmtime(path)
    while True:
        new_time = os.path.getmtime(path)
        if new_time != modtime:
            modtime = new_time
            yield modtime
        yield from asyncio.sleep(1)

@asyncio.coroutine
def printer():
    while True:
        modtime = yield from pathmonitor('/home/users/gnr/tempfile')
        print(modtime)

loop = asyncio.get_event_loop()
loop.run_until_complete(printer())
loop.run_forever()

我希望它能工作——但是,当我运行它时,我得到:

RuntimeError: Task got bad yield: 1426449327.2590399

我做错了什么?

更新:请参阅下面我的回答,了解观察者模式的示例(即,在不使用回调(您必须使用任务)的情况下,有效地允许多个注册者在文件被访问时获取更新)。

UPDATE2:对此有更好的修复:3.5 的 async for(异步迭代器):https://www.python.org/dev/peps/pep-0492/

最佳答案

我通过在链式协程中使用 return 而不是 yield 让你的代码工作,就像 chained coroutines example :

#!/usr/bin/env python3
import os
import asyncio2

@asyncio.coroutine
def pathmonitor(path):
    modtime = os.path.getmtime(path)
    while True:
        new_time = os.path.getmtime(path)
        if new_time != modtime:
            modtime = new_time
            return modtime
        yield from asyncio.sleep(1)


@asyncio.coroutine
def printer():
    while True:
        modtime = yield from pathmonitor('/tmp/foo.txt')
        print(modtime)


loop = asyncio.get_event_loop()
loop.run_until_complete(printer())
loop.run_forever()

请注意,printer() 的循环将为每次迭代创建一个新的 pathmonitor 生成器。不确定这是否是您的初衷,但这可能是一个开始。

我发现协程 API 和语法让我自己有点困惑。以下是一些我认为有帮助的读物:

关于python - 在 asyncio(和观察者模式)中链接协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29065579/

相关文章:

python - 使用 Python 从 txt 文件中仅提取所需的列?

python - Python 2.7 中的 Try 语句不返回值

python - 比较两个 csv 文件内容并将相似的内容存储到变量中

c - python 中的整数溢出

python - 使用 return 的优缺点(yield from some_function())

python - 使用 asyncpg 插入多行的最佳方法

Python循环遍历列表以在asyncio中获取api调用并保存结果

python - 使用 Python3(通过 Homebrew 安装)支持编译 vim?

python - 可视化修改后的 SIR 模型

python - 如何在Airflow中实现Canary DAG来进行其他作业的健康检查?