2014-10-03 11 views
5

Mam kod wykonywany w podprocesie, który ma wywołać wyjątek.Wyjątek Reraise z podprocesu

Chciałbym podnieść ten sam wyjątek w głównym procesie, gdy wyjątek jest zwracany z podprocesu (najlepiej przy zachowaniu śledzenia stosu), ale nie jestem pewien, jak to zrobić.

Przechwytywam stderr z podprocesu, ale nie mogę go znaleźć, więc otrzymuję wyjątek. Jak to osiągnąć?

ja Pythonie 2,7

główne metody

import subprocess 

example=subprocess.Popen(["python","example.py"], 
            stdout = subprocess.PIPE, 
            stderr = subprocess.PIPE) 
return_obj, return_error = example.communicate() 

if return_error: 
# replace with error from subprocess 
    print "Should raise ",NameError('HiThere') 
    raise TypeError('Wrong type') 

subprocess

raise NameError('HiThere') 
+0

Nie sądzę, że informacje są dla ciebie dostępne, bez przerabiania wyjątku i wyrzucania nowego. – wim

+0

Powinieneś rozważyć "importowanie" zamiast uruchamiania innego tłumacza. Zauważ, że nadal możesz uruchamiać dowolne funkcje wewnątrz 'przykładu.py' w oddzielnym procesie. – goncalopp

+0

'if return_error: raise Exception, return_error' –

Odpowiedz

3

Jeśli chcesz, aby twój kod Pythona działał w oddzielnym procesie, prawdopodobnie nie powinieneś używać subprocess. Jak powiedział Serge Ballesta, "celem jest uruchomienie innego programu na poziomie systemu operacyjnego, bez szczególnej troski o to, co to jest - nie ma nic, co mogłoby pomóc w prawidłowym postępowaniu z zawiłościami procesu interpretowania pythonów.

Dla tego rodzaju celów, to chyba najlepiej po prostu import kod i użyć multiprocessing, co naraża interfejs wysokiego szczebla w celu uruchomienia kodu Pythona w wielu procesach.

zakładając, że mają dobrze określoną main funkcję example.py:

from examply import main as example_main 
import multiprocessing 
pool= multiprocessing.Pool(1) 
pool.apply(example_main) 

przy użyciu tego kodu, zarówno wyjątki i zwracane wartości będą przejrzyście podane do głównego procesu.

Możesz także użyć Pool.apply_async, jeśli nie chcesz blokować czekania na wynik.

+0

Sytuacja, którą mam, polega na tym, że mój program akceptuje dane wejściowe na standardowe wejście i na pewnym wejściu powinien się zawiesić. Używam podprocesu do testowania tego zachowania.Czy można w tym celu zastosować proces wieloprocesowy? – Bomaz

+0

@Bomaz jest to wykonalne, ale dziwaczne - patrz sekcja [Wskazówki dotyczące programowania] (https://docs.python.org/2/library/multiprocessing.html#programming-guidelines) na temat zamiany 'stdin'. Łatwiej jest po prostu przepisać 'example.py', aby zaakceptować opcjonalny argument z obiektem pliku-pliku i przekazać go z twojego programu testującego. – goncalopp

+0

@Bomaz Lub użyj "wieloprocesorowych" mechanizmów wbudowanych (https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes), takich jak potok – goncalopp

1

Podproces wykonuje różne natywnego aplikacji. Może to być Java, C++, LISP, a nawet Fortran lub Cobol. Więc masz tylko 2 sposoby, aby uzyskać wyjątek od pytona podproces:

  • zapomnieć podproces w ogóle, a bezpośrednio wywołać kodu Pythona w tym samym programie Python, na prostych try except zrobi pracę
  • określić w umowa między głównym i podprocesowym, na przykład wymagająca, aby wynik błędu był pusty, jeśli nie wystąpi wyjątek ze skutkiem śmiertelnym, a ponadto zawiera zalążek wyjątku i stosu.