Python:await 在以下上下文中做什么?

用户1187968

我尝试从位于https://github.com/ajdavis/coroutines-demo/blob/master/50.py 的示例中学习协程它是由用户https://stackoverflow.com/users/618967/a-jesse-jiryu-davis在 2015年创建的

await f在代码中多次看到f是一个空的未来,为什么它需要是await有人可以更清楚地解释这个概念吗?

from selectors import DefaultSelector, EVENT_WRITE, EVENT_READ
import socket
import time

selector = DefaultSelector()
n_jobs = 0

class Future:
    def __init__(self):
        self.callback = None

    def resolve(self):
        self.callback()

    def __await__(self):
        yield self

class Task:
    def __init__(self, coro):
        self.coro = coro
        self.step()

    def step(self):
        try:
            f = self.coro.send(None)
        except StopIteration:
            return

        f.callback = self.step

async def get(path):
    global n_jobs
    n_jobs += 1
    s = socket.socket()
    s.setblocking(False)
    try:
        s.connect(('localhost', 5000))
    except BlockingIOError:
        pass

    f = Future()
    selector.register(s.fileno(), EVENT_WRITE, f)
    await f
    selector.unregister(s.fileno())

    s.send(('GET %s HTTP/1.0\r\n\r\n' % path).encode())
    buf = []

    while True:
        f = Future()
        selector.register(s.fileno(), EVENT_READ, f)
        await f
        selector.unregister(s.fileno())
        chunk = s.recv(1000)
        if chunk:
            buf.append(chunk)
        else:
            break

    # Finished.
    print((b''.join(buf)).decode().split('\n')[0])
    n_jobs -= 1

start = time.time()
Task(get('/foo'))
Task(get('/bar'))

while n_jobs:
    events = selector.select()
    for key, mask in events:
        future = key.data
        future.resolve()

print('took %.2f seconds' % (time.time() - start))
user2357112 支持莫妮卡

这段代码是一种奇怪的使用方式await大多数使用的await代码不像这段代码那样直接与协程实现交互。


Python 协程是在旧的迭代器和生成器机制之上实现的,并进行了一些额外的实施以避免将它们混淆。get就像一台发电机,并await f喜欢的作品yield from f.__await__()会如果f是一台发电机。由于f.__await__实现为yield self,因此await f行为类似于yield f(不要尝试用await f任何类型的替换yield- 手动yielding 在协程中的工作方式不同。)

您正在查看的代码将所有get协程包装在一个Task对象中,Task.step如下所示:

def step(self):
    try:
        f = self.coro.send(None)
    except StopIteration:
        return

    f.callback = self.step

f = self.coro.send(None)推进协程直到它产生一个 Future,并将 Future 分配给ff.callback = self.step设置未来的回调,稍后将调用future.resolve()

get调用selector.register(s.fileno(), EVENT_READ, f)这将使用选择器注册指定的文件,因此当文件准备好读取时, 的输出selector.select()将包含一个SelectorKey指示此事实的信息。作为第三个register参数传递的任何对象都将附加到SelectorKey,因此在这里, Future 将附加到SelectorKey

在以下循环中:

while n_jobs:
    events = selector.select()
    for key, mask in events:
        future = key.data
        future.resolve()

events = selector.select()等待任何已注册的文件可供读取。future = key.data从 中提取关联的 FutureSelectorKeyfuture.resolve()调用Task.step,这会推进关联的协程,直到它再次产生或终止。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Python在“ with”上下文中处理参数

来自分类Dev

在Python上下文中什么是运行时?它由什么组成?

来自分类Dev

在mod_python的上下文中,“扩展httpd”是什么意思?

来自分类Dev

在 Python 理解的上下文中什么是 **iterable 表达式**?

来自分类Dev

Python exec() 在其他上下文中

来自分类Dev

在上下文中更改python的打印行为

来自分类Dev

在特定目录的上下文中运行python unittest

来自分类Dev

在Python词典的上下文中了解对/错评估

来自分类Dev

在此上下文中接口的定义(python文章)

来自分类Dev

“[]”在以下上下文中代表什么?

来自分类Dev

在已经拆分的上下文中调用await时会产生开销吗?

来自分类Dev

为什么我已经在使用await时被要求使用(在此上下文中启动了第二个操作)?

来自分类Dev

在一个上下文中而不是另一个上下文中禁用python模块的日志记录

来自分类Dev

为什么在 Python 的打印函数中传递给关键字参数 end 的参数没有在下面的上下文中按预期工作?

来自分类Dev

为什么两个相同但连接不同的字符串在用python调用的shell上下文中具有不同的结果?

来自分类Dev

Fabric-Python 3-什么是上下文,上下文必须包含什么,为什么需要传递它?

来自分类Dev

git log --all 在分支差异的上下文中做什么?

来自分类Dev

在作为函数调用应用的上下文中,q @符号是做什么的?

来自分类Dev

异步上下文中的Python协程/生成器术语

来自分类Dev

多处理上下文中Python日志记录模块的混乱行为

来自分类Dev

如何告诉python传递给函数的意外变量类型在上下文中是正确的

来自分类Dev

使用标记将 python 字符串插入到 Django 模板上下文中

来自分类Dev

在Python中,如何在共享上下文中使用许多exec调用?

来自分类Dev

Python:检查globals()中变量的存在使其在本地上下文中不可见

来自分类Dev

在PyQt中将python类添加到Web Worker的上下文中

来自分类Dev

什么是git上下文中的“ Maildir”?

来自分类Dev

Python:如何创建在每个上下文中都不同的并发安全可重入上下文管理器

来自分类Dev

在以下代码的上下文中,为什么“ cout << c”是合法的而“ c =“ x””是非法的?

来自分类Dev

为什么在以下上下文中使用 Thread.Sleep() 以及如何避免它?

Related 相关文章

  1. 1

    Python在“ with”上下文中处理参数

  2. 2

    在Python上下文中什么是运行时?它由什么组成?

  3. 3

    在mod_python的上下文中,“扩展httpd”是什么意思?

  4. 4

    在 Python 理解的上下文中什么是 **iterable 表达式**?

  5. 5

    Python exec() 在其他上下文中

  6. 6

    在上下文中更改python的打印行为

  7. 7

    在特定目录的上下文中运行python unittest

  8. 8

    在Python词典的上下文中了解对/错评估

  9. 9

    在此上下文中接口的定义(python文章)

  10. 10

    “[]”在以下上下文中代表什么?

  11. 11

    在已经拆分的上下文中调用await时会产生开销吗?

  12. 12

    为什么我已经在使用await时被要求使用(在此上下文中启动了第二个操作)?

  13. 13

    在一个上下文中而不是另一个上下文中禁用python模块的日志记录

  14. 14

    为什么在 Python 的打印函数中传递给关键字参数 end 的参数没有在下面的上下文中按预期工作?

  15. 15

    为什么两个相同但连接不同的字符串在用python调用的shell上下文中具有不同的结果?

  16. 16

    Fabric-Python 3-什么是上下文,上下文必须包含什么,为什么需要传递它?

  17. 17

    git log --all 在分支差异的上下文中做什么?

  18. 18

    在作为函数调用应用的上下文中,q @符号是做什么的?

  19. 19

    异步上下文中的Python协程/生成器术语

  20. 20

    多处理上下文中Python日志记录模块的混乱行为

  21. 21

    如何告诉python传递给函数的意外变量类型在上下文中是正确的

  22. 22

    使用标记将 python 字符串插入到 Django 模板上下文中

  23. 23

    在Python中,如何在共享上下文中使用许多exec调用?

  24. 24

    Python:检查globals()中变量的存在使其在本地上下文中不可见

  25. 25

    在PyQt中将python类添加到Web Worker的上下文中

  26. 26

    什么是git上下文中的“ Maildir”?

  27. 27

    Python:如何创建在每个上下文中都不同的并发安全可重入上下文管理器

  28. 28

    在以下代码的上下文中,为什么“ cout << c”是合法的而“ c =“ x””是非法的?

  29. 29

    为什么在以下上下文中使用 Thread.Sleep() 以及如何避免它?

热门标签

归档