2014-10-30 56 views
0

我想知道當您想從Python腳本「返回」某些東西時,最佳做法是什麼。Python subprocess.Popen:sys.stdout vs .txt文件vs Cpickle.dump

這是我的問題。我使用subprocess.Popen方法從parentScript運行Python childScript。我想從第一個腳本的執行中得到兩個浮點數的元組。現在

,我所看到的第一種方法是通過使用sys.stdout的和管在子功能如下:

child.py:

if __name__ == '__main__': 
    myTuple = (x,y) 
    sys.stdout.write(str(myTuple[0]) +":"+str(myTuple[1])) 
    sys.stdout.flush() 

parent.py:

p = subprocess.Popen([python, "child.py"], stdout=subprocess.PIPE) 
out, err = p.communicate() 

雖然here它說這不是在大多數情況下推薦,但我不知道爲什麼...

第二種方法是將我的元組寫入Script1.py中的文本文件並在Script2.py中打開它。但是我認爲寫入和讀取文件需要一些時間,所以我不知道這是否是更好的方法?

最後,我可以使用CPickle並轉儲我的元組並從script2.py中打開它。我想這會比使用文本文件快一點,但會比使用sys.stdout更好嗎?

什麼是正確的方法?

---------------------------------------編輯------ ------------------------------------------

我忘了提及我無法使用導入,因爲parent.py實際上在文件夾中生成child.py。事實上,我正在做一些多處理。

Parent.py創建了10個目錄,其中child.py在每個目錄中被複制。然後我在幾個處理器上運行parent.py中的每個child.py。我希望parent.py收集所有child.py的「返回」結果。所以parent.py不能導入child.py,因爲它還沒有生成,或者我可以做一些動態導入?我不知道...

-------------------------------------- -EDIT2 -----------------------------------------------

另一個編輯回答關於爲什麼我以這種方式進行的問題。 Child.py實際上調用Ironpython和另一個腳本來運行.Net程序集。之所以我必須複製特定文件夾中的所有child.py文件,是因爲此程序集生成了一個資源文件,然後由它自己使用。如果我不在每個子文件夾中複製child.py(以及程序集),則會在使用多處理模塊調用多個進程時在根處複製資源文件,這會造成衝突。如果你對這個整體架構有一些建議,那麼歡迎:)。

感謝

+0

無關:使用subprocess模塊裝配在一般情況下,'script1.py','script2.py','float1','float2'都不好名字。如果沒有更具體的想法和'數字'或'x,y'這些數字,您可以使用'child.py','parent.py'作爲腳本。 – jfs 2014-10-30 14:24:54

+0

好的,我正在編輯/補充它。 謝謝! – Serge 2014-10-30 14:31:36

回答

2

平凡,你應該使用import other_module和調用各種功能:

import other_module 

x, y = other_module.some_function(param='z') 

如果你可以運行腳本,你也可以將其導入。

如果你想使用subprocess.Popen()然後通過一些浮點數,你可以使用json格式:它是人類可讀的,確切的(在這種情況下),它是機器可讀的。例如:

child.py

#!/usr/bin/env python 
import json 
import sys 

numbers = 1.2345, 1e-20 
json.dump(numbers, sys.stdout) 

parent.py

#!/usr/bin/env python 
import json 
import sys 
from subprocess import check_output 

output = check_output([sys.executable, 'child.py']) 
x, y = json.loads(output.decode()) 

Child.py實際上調用IronPython和另一個腳本運行.NET程序集。之所以我必須複製所有child.py文件,是因爲此程序集會生成一個資源文件,然後由它使用。如果我不在每個子文件夾中複製child.py,則會在使用多處理模塊調用多個進程時創建衝突的根處複製資源文件。如果你對這個整體架構有一些建議,那麼歡迎:)。

你可以把從child.py代碼爲parent.py並調用os.chdir()(後叉)在其自己的工作目錄執行每個multiprocessing.Process或使用cwd參數(它設置子進程的當前工作目錄),如果您運行

#!/usr/bin/env python 
import os 
import shutil 
import tempfile 
from multiprocessing import Pool 

def init(topdir='.'): 
    dir = tempfile.mkdtemp(dir=topdir) # parent is responsible for deleting it 
    os.chdir(dir) 

def child(n): 
    return os.getcwd(), n*n 

if __name__ == "__main__": 
    pool = Pool(initializer=init) 
    results = pool.map(child, [1,2,3]) 
    pool.close() 
    pool.join() 
    for dirname, _ in results: 
     try: 
      shutil.rmtree(dirname) 
     except EnvironmentError: 
      pass # ignore errors 
+0

我忘了提及我無法使用導入,因爲script2實際上在文件夾中生成script1。事實上,我正在做一些多處理。 Script2創建了10個目錄,其中script1被複制到每個目錄中。然後我從script2運行每個script1。我希望script2收集所有腳本1「返回」的結果。所以script2不能導入script1,因爲它還沒有生成,或者我可以做某種動態導入?我不知道。 但我會看看json。謝謝! – Serge 2014-10-30 14:30:37

+1

@ user2390615:1.任何其他信息應該轉到您的問題而不是評論,以便其他人可以輕鬆找到它。 2.如果腳本尚未生成,那麼您也不能使用子進程運行它。 :)如果文件已經存在,那麼你可以導入它(將頂級代碼移到一個函數中,以避免在導入時執行它)。 3.動態生成腳本並複製它們聽起來不像一個好設計 - 您應該仔細觀察它。 – jfs 2014-10-30 14:45:24

+0

我編輯了這個問題。謝謝。 – Serge 2014-10-30 14:48:05