2014-10-30 11 views
0

파이썬 스크립트에서 무언가를 "반환"하고 싶을 때 가장 좋은 방법이 무엇인지 알고 싶습니다.파이썬 subprocess.Popen : sys.stdout 대 .txt 파일 대 Cpickle.dump

여기 내 문제입니다. subprocess.Popen 메서드를 사용하여 parentScript에서 Python childScript를 실행하고 있습니다. 첫 번째 스크립트를 실행하여 두 개의 부동 소수점을 하나씩 얻고 싶습니다.

child.py :

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

parent.py :

지금, 본 첫 번째 방법은 다음과 서브 프로세스 함수 sys.stdout와 파이프를 사용하는 것이다

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

here 비록 대부분의 경우에는 권장되지 않지만 이유는 모르겠다 고합니다 ...

두 번째 방법은 내 튜플을 Script1.py의 텍스트 파일에 쓰고 Script2.py에서 엽니 다. 하지만 필자는 파일을 쓰고 읽는 데 약간의 시간이 걸리는 것 같아서 더 좋은 방법인지는 모르겠다.

마지막으로 CPickle을 사용하고 내 튜플을 덤프하고 script2.py에서 열 수 있습니다. 텍스트 파일을 사용하는 것보다 조금 빠르지 만 sys.stdout을 사용하는 것보다 낫겠습니까?

올바른 방법은 무엇입니까?

--------------------------------------- EDIT ------ ------------------------------------------

내가 깜박했다. parent.py는 실제로 폴더에서 child.py를 생성하기 때문에 import를 사용할 수 없다. 실제로 나는 다중 처리를하고있다.

parent.py는 child.py가 각각 복사되는 10 개의 디렉토리를 만듭니다. 그런 다음 여러 프로세서에서 parent.py의 child.py를 실행합니다. 그리고 모든 child.py에 의해 "반환 된"결과를 모으기를 원합니다. 그래서 parent.py는 아직 생성되지 않았기 때문에 child.py를 import 할 수 없거나, 일종의 dynamic import를 할 수 있습니까? 모르겠다. ...

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

왜 이런 식으로 진행되는지에 대한 질문에 대답하는 또 다른 편집. Child.py는 실제로 ironpython과 .Net 어셈블리를 실행하는 다른 스크립트를 호출합니다. 특정 폴더에있는 모든 child.py 파일을 복사해야하는 이유는이 어셈블리가 자체적으로 사용되는 리소스 파일을 생성하기 때문입니다. 각 하위 폴더에서 child.py (및 어셈블리를 복사하지 않으면) 다중 프로세스 모듈을 사용하여 여러 프로세스를 호출 할 때 충돌을 만드는 리소스 파일이 루트에 복사됩니다. 이 전반적인 아키텍처에 대한 몇 가지 제안 사항이 있으시면 환영받는 것 이상입니다. :)

+0

: subprocess 모듈을 사용하여 어셈블리 일반적으로'script1.py','script2.py','float1','좋은 이름 float2' 수 없습니다. 더 구체적으로 염두에 두지 않으면 숫자에 대해'numbers' 또는'x, y'를 쓰면 스크립트에'child.py','parent.py'를 사용할 수 있습니다. – jfs

+0

좋아, 지금 편집 중이거나 보완 중입니다. 감사합니다. – Serge

답변

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과 닷넷 어셈블리를 실행하는 다른 스크립트를 호출합니다. 이 어셈블리가 리소스 파일을 생성하고 그 리소스 파일에 의해 사용되기 때문에 모든 child.py 파일을 복사해야하는 이유가 있습니다. 각 하위 폴더에서 child.py를 복사하지 않으면 자원 파일이 루트에 복사되어 다중 처리 모듈을 사용하는 여러 프로세스를 호출 할 때 충돌이 발생합니다. 이 전반적인 아키텍처에 대한 몇 가지 제안 사항이 있으시면 환영받는 것 이상입니다. :) 당신이 실행하는 경우

당신은 parent.pychild.py의 코드를 넣어 자신의 작업 디렉토리에있는 각 multiprocessing.Process을 실행하거나 cwd 매개 변수를 사용하여 (포크 후) os.chdir()를 호출 할 수 있습니다

은 (는 서브 프로세스의 현재 작업 디렉토리를 설정) 관련이없는

#!/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는 각각에 script1이 복사되는 10 개의 디렉토리를 만듭니다. 그런 다음 script2에서 각 script1을 실행합니다. 그리고 script2가 모든 script1에 의해 "반환 된"결과를 수집하기를 원합니다. 그래서 script2는 아직 생성되지 않았기 때문에 script1을 import 할 수 없거나, 어떤 종류의 dynamic import를 할 수 있습니까? 나는 모른다. 하지만 나는 json을 살펴볼 것입니다. 감사! – Serge

+1

@ user2390615 : 1. 다른 추가 정보는 다른 사람이 쉽게 찾을 수 있도록 주석 대신 질문에 가야합니다. 2. 스크립트가 아직 생성되지 않은 경우 하위 프로세스를 사용하여 실행할 수 없습니다. :) 파일이 이미 있으면 가져올 수 있습니다 (최상위 코드를 함수로 가져 와서 가져 오기 실행을 피하십시오). 3. 스크립트를 즉석에서 생성하고 복사하는 것은 좋은 디자인처럼 들리지 않습니다. 더 자세히 살펴 봐야합니다. – jfs

+0

질문을 편집했습니다. 감사. – Serge