1

Python 没有内置的 OutputIterator 等价物。特别是,内置或标准库容器不支持任何允许客户端代码在不知道特定容器类型的情况下向它们发送数据的通用接口。

根据@Steven Rumbalski 的评论@Glenn Maynard 的回答,这通常不是问题,因为在 C++ 中将采用 OutputIterator 参数的函数在 python 中将被简单地编写为生成器。

通常,我使用生成器没有问题,并且从不觉得我需要 Python 中的 OutputIterator。但是,在这种情况下,我被卡住了。

我正在用 Python 重新实现 Boost Graph Library 中的一些算法。一个典型的图遍历算法,比如说depth_first_search,将“访问者”对象作为参数。访问者本质上是一组回调函数,当遍历算法在其执行过程中遇到不同的事件(例如,发现新顶点、检查边等)时,它会调用这些回调函数。在 C++ 中,我可以让这些回调函数中的一个或多个将数据发送到访问者对象在其初始化时从客户端代码获得的 OutputIterator 对象。(例如,这正是topological_sort实现的方式:它接受一个 OutputIterator,将其传递给一个dfs_visitor对象,然后访问者对象“监视”事件finished_vertex并将它接收到的顶点发送到指定的OutputIterator。当然,更复杂的情况需要多个 OutputIterator 对象和多个回调函数。)

如何使用 Python 生成器实现相同的目标?

我需要以某种方式以生成器“样式”将数据从depth_first_search多个指定的数据消费者发送。我只是不知道该怎么做。(我使用的是 Python 3.3。)

4

3 回答 3

1

我认为,该generator.send方法在这里可以满足您的要求:

def depth_first_search(some_args, edge_consumer, vertex_consumer):
    # start the generators
    next(edge_consumer)
    next(vertex_consumer)

    ...
    edge_consumer.send(some_edge)
    vertex_consumer.send(some_vertex)

    ...
    # this raises GeneratorExit at the `yield` in the generator
    edge_consumer.close()
    vertex_consumer.close()

def edge_handler():
    while True:
        e = yield
        print "E", e

def vertex_handler():
    while True:
        v = yield
        print "V", v

depth_first_search(..., edge_handler(), vertex_handler())
于 2013-04-25T08:23:54.147 回答
1

你可以只传递回调函数吗?

def depth_first_search(some_args, on_edge=lambda e:None, on_vertex=lambda v:None):
    ...
    on_edge(some_edge)
    on_vertex(some_vertex)

def edge_handler(e):
    print "E", e

def vertex_handler(v):
    print "V", v

depth_first_search(..., on_edge=edge_handler, on_vertex=vertex_handler)

或产生一个目的地:

def depth_first_search(some_args, on_edge=lambda e:None, on_vertex=lambda v:None):
    ...
    yield "edge", some_edge
    yield "vertex", some_vertex

for t, value in depth_first_search(...):
    if t == 'edge':
        # ...
    elif t == 'vertex':
        # ...
于 2013-04-25T08:07:17.173 回答
0

我不知道这是否可行,但是使用像 multimethods 这样的库来实现多调度函数来完成您需要的工作怎么样?我的 Internet 出现 DNS 问题,因此我无法查找语法,因此您将获得伪代码而不是真正的 Python,但这里是我所谈论内容的一般概念:

def send_to(data, consumer):
    workfunc = dispatch(type(consumer))
    workfunc(data, consumer)

def send_to_list(data, consumer):
    consumer.append(data)

def send_to_set(data, consumer):
    consumer.add(data)

def send_to_file_obj(data, consumer):
    consumer.write(data)

当然,需要一些管道来将工作功能连接到调度功能,这就是我现在实际上无法查找的内容,因为我的 DNS 已关闭。(幸运的是,StackOverflow 仍在我的浏览器缓存中)。所以我担心这个答案很笼统,缺乏细节,但希望它至少能为你指明一个有用的方向。

于 2013-04-25T08:18:49.403 回答