使用Python生成器替换C ++ STL输出迭代器 [英] Replacing C++ STL output iterator with a Python generator

查看:157
本文介绍了使用Python生成器替换C ++ STL输出迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



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

如何用Python生成器实现相同的功能?



我需要以某种方式发送数据,样式,从 depth_first_search 到多个指定的数据使用者。我只是不知道如何做到。 (我使用的是Python 3.3。)

解决方案

generator.send 方法在这里做你想要的,

  def depth_first_search(some_args,edge_consumer,vertex_consumer):
#启动生成器
next(edge_consumer)
next(vertex_consumer)

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

...
edge_consumer.close()
vertex_consumer.close()

def edge_handler():
try:
while True:
e = yield
打印E,e
,除了GeneratorExit:
return

def vertex_handler():
try:
while True:
v = yield
printV,v
,除了GeneratorExit:
return


depth_first_search(...,edge_handler(),vertex_handler ))


Python doesn't have a builtin equivalent of OutputIterator; in particular, builtin or standard library containers do not support any generic interface that allows client code to send data to them without knowing the specific container type.

According to @Steven Rumbalski's comment and @Glenn Maynard's answer, this is not usually a problem because a function that in C++ would have taken an OutputIterator argument, in python would be simply written as a generator.

Normally, I have no problem using generators, and never felt I needed an OutputIterator in Python. However, in this one case, I'm stuck.

I am re-implementing in Python some of the algorithms from the Boost Graph Library. A typical graph traversal algorithm, say depth_first_search, takes as a parameter a "visitor" object. The visitor is essentially a bunch of callback functions that the traversal algorithm calls as it encounters different events in its execution (e.g., discovering a new vertex, examining an edge, etc.). In C++, I can have one or several of these callback functions send data to the OutputIterator objects that the visitor object obtained at its initialization from the client code. (For instance, that's precisely how topological_sort is implemented: it takes an OutputIterator, passes it to a dfs_visitor object, the visitor object then "monitors" the event finished_vertex and sends the vertexes it receives to the specified OutputIterator. Of course, more complex cases require multiple OutputIterator objects and multiple callback functions.)

How do I achieve the same with Python generators?

I need to somehow send data, in the generator "style", from depth_first_search to multiple designated data consumers. I just can't figure out how to do it. (I'm using Python 3.3.)

解决方案

The generator.send method does what you want here, I think:

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)

    ...
    edge_consumer.close()
    vertex_consumer.close()

def edge_handler():
    try:
        while True:
            e = yield
            print "E", e
    except GeneratorExit:
        return

def vertex_handler():
    try:
        while True:
            v = yield
            print "V", v
    except GeneratorExit:
        return


depth_first_search(..., edge_handler(), vertex_handler())

这篇关于使用Python生成器替换C ++ STL输出迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆