使用Python生成器替换C ++ STL输出迭代器 [英] Replacing C++ STL output iterator with a Python generator
问题描述
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屋!