我正在尝试从Tkinter gui中显示的python multiprocessing进程获取输出。
我可以通过gui将进程的输出发送到命令外壳,例如,通过在外壳提示符下运行下面的微小脚本:
from multiprocessing import Process
import sys
def myfunc(text):
print text
sys.stdout.flush()
def f1():
p1 = Process(target = myfunc, args = ("Surprise",))
p1.start()
def f2():
p2 = Process(target = myfunc, args = ("Fear",))
p2.start()
def fp():
myfunc("... and an almost fanatical devotion to the Pope")
a = Tk()
b1 = Button(a, text="Process 1", command=f1)
b1.grid(row=0, column=0, pady=10, padx=10, sticky=SE)
b2 = Button(a, text="Process 2", command=f2)
b2.grid(row=0, column=1, pady=10, padx=10, sticky=SE)
b3 = Button(a, text="Parent", command=fp)
b3.grid(row=0, column=2, pady=10, padx=10, sticky=SE)
if __name__ == "__main__":
a.mainloop()
我还可以将输出从 父级 发送到文本框,例如,通过注释掉myfunc中的stdout的刷新来修改上面的内容
# sys.stdout.flush()
并在“ b3.grid …”行之后立即添加以下内容:
class STDText(Text):
def __init__(self, parent, cnf={}, **kw):
Text.__init__(self, parent, cnf, **kw)
def write(self, stuff):
self.config(state=NORMAL)
self.insert(END, stuff)
self.yview_pickplace("end")
self.config(state=DISABLED)
messages = STDText(a, height=2.5, width=30, bg="light cyan", state=DISABLED)
messages.grid(row=1, column=0, columnspan=3)
sys.stdout = messages
但是我不知道如何将输出从进程发送到文本框。我是否缺少简单的东西?
您可以将stdout /
stderr重定向到myfunc()中的StringIO,然后将写入该StringIO的所有内容发送回父级(如unutbu所建议)。
由于该示例的功能超出了您的需要,因此以下版本更符合您的既定目标:
#!/usr/bin/env python
import sys
from cStringIO import StringIO
from code import InteractiveConsole
from contextlib import contextmanager
from multiprocessing import Process, Pipe
@contextmanager
def std_redirector(stdin=sys.stdin, stdout=sys.stdin, stderr=sys.stderr):
tmp_fds = stdin, stdout, stderr
orig_fds = sys.stdin, sys.stdout, sys.stderr
sys.stdin, sys.stdout, sys.stderr = tmp_fds
yield
sys.stdin, sys.stdout, sys.stderr = orig_fds
class Interpreter(InteractiveConsole):
def __init__(self, locals=None):
InteractiveConsole.__init__(self, locals=locals)
self.output = StringIO()
self.output = StringIO()
def push(self, command):
self.output.reset()
self.output.truncate()
with std_redirector(stdout=self.output, stderr=self.output):
try:
more = InteractiveConsole.push(self, command)
result = self.output.getvalue()
except (SyntaxError, OverflowError):
pass
return more, result
def myfunc(conn, commands):
output = StringIO()
py = Interpreter()
results = ""
for line in commands.split('\n'):
if line and len(line) > 0:
more, result = py.push(line + '\n')
if result and len(result) > 0:
results += result
conn.send(results)
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
commands = """
print "[42, None, 'hello']"
def greet(name, count):
for i in range(count):
print "Hello, " + name + "!"
greet("Beth Cooper", 5)
fugazi
print "Still going..."
"""
p = Process(target=myfunc, args=(child_conn, commands))
p.start()
print parent_conn.recv()
p.join()
有关安全性的通常警告适用于此(即,除非您可以相信这些代码段的发送者不要做任何愚蠢/恶意的操作,否则请不要这样做。)
另请注意,如果您不需要解释python表达式 和 语句的任意组合,则可以简化很多操作。如果只需要调用生成某些输出的顶级函数,则可能更合适:
def dosomething():
print "Doing something..."
def myfunc(conn, command):
output = StringIO()
result = ""
with std_redirector(stdout=output, stderr=output):
try:
eval(command)
result = output.getvalue()
except Exception, err:
result = repr(err)
conn.send(result)
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
command = "dosomething()"
p = Process(target=myfunc, args=(child_conn, command))
p.start()
print parent_conn.recv()
p.join()
问题内容: 我可以导入什么以模拟Java中的键盘按下? 因此,例如,我可以使用它制作一个程序,以便在事件发生时自动按下“ a”键。 问题答案: 您需要的一切都在 例:
问题内容: 我有两个卡夫卡喷口,我要将其值发送到同一螺栓。 可能吗 ? 问题答案: 是的,有可能: 您也可以使用任何其他分组。 更新: 为了区分使用者螺栓中的元组(即topic_1或topic_2),有两种可能性: 1)您可以使用操作员ID(如@ user-4870385所建议): 2)您可以使用流名称(@zenbeni建议)。对于这种情况,两个喷口都需要声明命名流,而螺栓需要通过流名称连接到喷口
问题内容: 我有一个现有的应用程序,它针对log4j进行所有日志记录。我们使用了许多其他库,它们也使用log4j或对照Commons Logging进行日志记录,而这些日志最终在我们的环境中使用log4j记录。我们的依赖项之一甚至针对slf4j记录日志,它也可以正常工作,因为它最终也可以委托给log4j。 现在,我想为一些缓存需求将ehcache添加到此应用程序。先前版本的ehcache使用com
我最终尝试使用维特尔蒂API发送传真。我在 EC2 上有一个 API,我从我的 React 原生应用程序调用它: 但是,这会返回错误。如果我将的值改为类似于
问题内容: 我有。我希望在运行时在终端中显示ddrescue并将输出写入文件drclog。我尝试使用,但这使我在ddrescue中输入错误。 问题答案: 如果将其stdout / stderr重定向到管道时仍不更改其输出,则可以使用实用程序在终端上显示输出并将其保存到文件中: 如果确实如此,那么您可以尝试使用实用程序提供一个伪tty : 如果它直接写入终端,则可以用来捕获输出: 默认情况下,输出保
问题内容: 我的工作按日期处理数据,需要将输出写入特定的文件夹结构。当前的期望是生成如下结构: 等等 在任何时候,我最多只能获得12个月的数据,因此,我正在使用类在驱动程序中使用以下函数创建12个输出: 在reducer中,我添加了一个清理功能,以将生成的输出移动到适当的目录。 问题:在将输出从_temporary目录移动到输出目录之前,reducer的清除功能正在执行。因此,由于所有数据仍位于_