8

我是 IPython 新手,想在运行 IPython 并行集群函数时将中间结果打印到标准输出。(我知道对于多个进程,这可能会破坏输出,但这很好——它只是用于测试/调试,而且我正在运行的进程足够长,这样的冲突不太可能发生。)我检查了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 中的打印语句永远不会打印,即使所有进程都已返回。我究竟做错了什么?如何让“打印”工作?

4

1 回答 1

9

它实际上比你想象的更相似subprocess.Popen( ... , stdout=PIPE)。就像Popen对象有一个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

是一个展示了所有这些的笔记本

根据您的问题,需要注意一些事项:

  1. 在输出准备好之前,您必须等待 AsyncResult 完成(async.get()
  2. display_outputs()不返回任何东西 - 它实际上是打印/显示本身,所以print(async.display_outputs())没有意义。
于 2013-03-08T19:54:56.197 回答