2008-08-24 54 views

回答

9

如果你正在談論的Python解釋器或cmd.exe,這就是你的腳本的「父」,則沒有,這是不可能的。在每一個類似POSIX的系統中(現在你正在運行Windows,看起來,這可能有一些我不知道的怪癖,YMMV),每個進程有三個流,標準輸入,標準輸出和標準錯誤。卜默認這些被定向到控制檯,但重定向可以使用管道符號(在控制檯上運行時):

python script_a.py | python script_b.py 

這關係腳本的標準輸出流至腳本B的標準輸入流在這個例子中,標準錯誤仍然在控制檯上。請參閱維基百科上關於standard streams的文章。

如果你在談論一個子進程,你可以從Python啓動它,像這樣(標準輸入也是一種選擇,如果你想雙向通信):

import subprocess 
# Of course you can open things other than python here :) 
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
x = process.stderr.readline() 
y = process.stdout.readline() 
process.wait() 

的信息請參見Python的subprocess模塊管理流程。對於通信,process.stdin和process.stdout管道被認爲是標準的file objects

對於管道的使用,從標準輸入讀爲lassevk建議你做這樣的事情:

import sys 
x = sys.stderr.readline() 
y = sys.stdin.readline() 

sys.stdin和sys.stdout的是標準的文件對象如上所述,在sys定義模塊。您可能還想看看pipes模塊。

用的ReadLine()作爲我的例子中讀數據,雖然獲取數據的一個非常原始的方法。如果輸出不是面向行或不確定的,你可能想看看polling,但不幸的是它不能在Windows中工作,但我確信有一些替代方法。

+1

請注意,使用subprocess.Popen()調用Python時,傳遞「-u」標誌通常會有幫助,該標誌禁用stdin/stdout/stderr上的緩衝。當孩子開始讀取標準輸入時,如果輸出已被重定向到管道,Python不會自動刷新標準輸出,因此您可以最終阻止永久讀取緩衝的輸出。我遇到了這個問題,試圖包裝/自動化pdb。 – 2011-11-18 16:29:49

0

在哪些方面你問?

你們是不是要捕獲從你在命令行上啓動一個程序的輸出?

如果是這樣,那麼這是如何執行它:

somescript.py | your-capture-program-here 

和讀取輸出,從標準輸入剛纔讀。

如果,另一方面,你執行該腳本或cmd.exe,或類似從您的程序中,並要等到腳本/程序已完成,並捕獲所有的輸出,那麼你需要看看你用來啓動外部程序的庫調用,很可能有辦法讓它給你一些方法來讀取輸出並等待完成。

1

你想subprocess。在17.1.1中特別注意Popen,並在17.1.2中進行交流。

3

其實,你一定可以,同時它又美又醜又瘋了!

您可以用收集輸出的StringIO對象替換sys.stdout和sys.stderr。

下面是一個例子,它保存爲evil.py:

import sys 
import StringIO 

s = StringIO.StringIO() 

sys.stdout = s 

print "hey, this isn't going to stdout at all!" 
print "where is it ?" 

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n') 
sys.stderr.write(s.getvalue()) 

當你運行這個程序,你會發現:

  • 沒事就去到標準輸出(其中打印通常版畫)
  • 寫入stderr的第一個字符串是以'It'開頭的字符串
  • 接下來的兩行是在StringIO對象中收集的那一行

像這樣替換sys.stdout/err是所謂的monkeypatching的應用程序。無論這種「支持」是什麼,意見可能會有所不同,它絕對是一種醜陋的黑客攻擊,但它在試圖環繞外部事物一次或兩次時拯救了我的培根。

在Linux上進行測試,而不是在Windows上進行測試,但它應該也能正常工作。讓我知道它是否適用於Windows!

4

我想我可以指出你的問題的第一部分的一個很好的答案。

1.    是否有可能從一個Python腳本 捕捉Python解釋器的輸出?

答案是「」,並親自我喜歡從PEP 343 -- The "with" Statement文檔中的例子下面舉。

from contextlib import contextmanager 
import sys 

@contextmanager 
def stdout_redirected(new_stdout): 
    saved_stdout = sys.stdout 
    sys.stdout = new_stdout 
    try: 
     yield None 
    finally: 
     sys.stdout.close() 
     sys.stdout = saved_stdout 

而這樣使用的:

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

它的一個好的方面是,它可以應用於選擇性地圍繞只是一個腳本的執行的一部分,而不是它的整個範圍,並停留在效果即使在其上下文中引發了未處理的異常。如果你第一次使用後,重新打開附加模式的文件,你可以積累的結果到單個文件:

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

print "screen only output again" 

with stdout_redirected(open("filename.txt", "a")): 
    print "Hello world2" 

當然,上述也可以擴展到也重定向sys.stderr相同或另一個文件。另請參閱此answer相關問題。

相關問題