gpt4 book ai didi

python - 在 Tornado 协程中使用常规 Python 生成器

转载 作者:行者123 更新时间:2023-11-30 23:04:53 24 4
gpt4 key购买 nike

Python 生成器是一个很棒的功能。它允许我对复杂的、可能递归的遍历逻辑进行编码,并将其与用户解耦。通常我像下面的代码一样使用它

TREE = {
1: [2,3],
2: [],
3: [4,5],
4: [6],
5: [],
6: []
}

def query_children(node):
return TREE[node]

def walk_tree(root):
# recursive tree traversal logic
yield root
children = query_children(root)
for child in children:
for node in walk_tree(child):
yield node

def do_something():
# nice linear iterator
for node in walk_tree(root):
print(node)

Tornado 使用生成器来实现协程,这也是构建无需回调的异步函数的好方法。

但是,当尝试同时使用两者时,我可能会感到困惑。

@gen.coroutine
def query_children(node):
...
raise gen.Return(children)


def walk_tree(root):
# recursive tree traversal logic
yield root
children = yield query_children(root)
for child in children:
for node in walk_tree(child):
yield node


def do_something():
# nice linear iterator
for node in walk_tree(root):
print(node)

在新的 walk_tree 中,第一个产量是常规的 Python 产量。第二个产量是 Tornado 的。他们俩能一起工作吗?

最佳答案

Python 生成器协议(protocol)基于同步接口(interface);不可能使用像协程这样的异步代码作为与 for 一起使用的生成器的一部分(协程最重要的规则:任何调用协程的东西都必须也可以是一个协程,或者至少知道协程。for语句对它们一无所知,它就是调用你的生成器的。相反,我建议使用 tornado.queues.Queue:

@gen.coroutine
def query_children(node):
...
raise gen.Return(children)


def walk_tree(queue, root):
# recursive tree traversal logic
yield root
children = yield query_children(root)
for child in children:
for node in walk_tree(child):
yield queue.put(node)
yield queue.put(None)


def do_something():
queue = tornado.queues.Queue()
IOLoop.current().spawn_callback(walk_tree, queue, root)
while True:
node = yield queue.get()
if node is None:
break
print(node)

关于python - 在 Tornado 协程中使用常规 Python 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33482066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com