我是IPython的新手,并且想在运行IPython并行集群函数时将中间结果打印到stdout。 (我知道在多个进程中,这可能会破坏输出,但这很好-它仅用于测试/调试,而且我要运行的进程足够长,因此不太可能发生这种冲突。)我检查了IPython的文档,但找不到打印并行化函数的示例。
基本上,我正在寻找一种将子流程的打印输出重定向到主标准输出的方法,该标准输出与IPython等效。

subprocess.Popen( ... , stdout=...)

在进程内部打印不起作用:
rc = Client()
dview = rc()
def ff(x):
    print(x)
    return x**2
sync = dview.map_sync(ff,[1,2,3,4])
print('sync res=%s'%repr(sync))
async = dview.map_async(ff,[1,2,3,4])
print('async res=%s'%repr(async))
print(async.display_outputs())

退货
sync res=[1, 4, 9, 16]
async res=[1, 4, 9, 16]

因此,计算可以正确执行,但是即使在所有进程都返回后,函数ff中的print语句也不会被打印。
我究竟做错了什么?如何获得“打印”功能?

最佳答案

实际上,它与subprocess.Popen( ... , stdout=PIPE)的相似程度超出了您的预期。
就像Popen对象具有stdout属性一样,您可以阅读该属性以查看子流程的stdout,
AsyncResult具有stdout属性,该属性包含从引擎捕获的标准输出。
确实不同之处在于AsyncResult.stdout是字符串的列表,其中列表中的每个项目都是单个引擎作为字符串的标准输出。

因此,开始:

rc = parallel.Client()
dview = rc[:]
def ff(x):
    print(x)
    return x**2
sync = dview.map_sync(ff,[1,2,3,4])
print('sync res=%r' % sync)
async = dview.map_async(ff,[1,2,3,4])
print('async res=%r' % async)
async.get()


sync res=[1, 4, 9, 16]
async res=<AsyncMapResult: ff>

我们可以看到AsyncResult.stdout字符串列表:
print(async.stdout)
['1\n2\n', '3\n4\n']

我们可以看到异步结果的标准输出:
print('async output:')
async.display_outputs()

打印:
async output:
[stdout:0]
1
2
[stdout:1]
3
4

here is a notebook展示了所有这些。

根据您的问题,需要注意一些事项:
  • 您必须等待AsyncResult完成,然后才能准备好输出(async.get())
  • display_outputs()不返回任何内容-它实际上会自行打印/显示,因此print(async.display_outputs())没有任何意义。
  • 关于python - 在IPython并行进程中打印到标准输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15289168/

    10-17 01:36