用Python Gen替换C++ STL输出迭代器

2024-05-23 17:26:52 发布

您现在位置:Python中文网/ 问答频道 /正文

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

<^ >根据@Steven Rumbalski's comment@Glenn Maynard's answer,这通常不是问题,因为C++中的函数将采取一个OutuPutter参数,在Python中,它将被简单地写成生成器。在

通常,我在使用生成器时没有问题,也从来没有觉得我需要Python中的OutputIterator。但是,在这件事上,我被卡住了。在

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

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

我需要以某种方式以生成器“样式”将数据从depth_first_search发送到多个指定的数据使用者。我就是不知道怎么做。(我使用的是python3.3。)


Tags: 对象函数代码算法客户端search参数情况
3条回答

我认为,^{}方法可以满足您的需要:

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())

你能只传递回调函数吗?在

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)

或者让出一个目的地:

^{pr2}$

我不知道这是否可行,但是使用像multimethods这样的库来实现一个多分派函数来完成您需要的任务呢?我的互联网出现了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仍在我的浏览器缓存中)。所以,我担心这个答案过于笼统,缺乏细节,但希望它至少能为你指明一个有用的方向。在

相关问题 更多 >