2016-03-04 4 views
-1

Допустим, у меня есть следующий поток выполнения:Исключение просачивания в Linux/питон

 def method1: 
      try: 
      method2() 
      except Exception as e: 
      handle_exception() 

     def method2: 
      command = "<some linux command>" 
      status = execute_command(command) 
      if status != 0: 
      log_exception() 

     def execute_command(command): 
      subprocess.popen(command, <other params>) 

     method1() 

command.py

with open(path, 'w') as f: #this raises IOError 
     #do something 

Будет handle_exception() называться? Мое понимание трассировки будет напечатано вместо этого, поскольку исключение не будет просачиваться до method1. И это потому, что execute_command(..) породит другой процесс, который будет иметь собственный стек вызовов. Правильно ли я понимаю?

+0

Из кода, который вы указали, да, 'handle_exception' будет вызываться, потому что' method2' вызывает исключение или, более явно, 'execute_command' вызывает исключение, которое не обрабатывается' method2', таким образом оно поднимается в стек вызовов. –

+0

Почему бы вам не попробовать запустить несколько команд 'print()', чтобы увидеть, что он делает? Я нашел, что это отличный способ узнать такие вещи :-) – Carpetsmoker

+0

И следите, когда вы редактируете свои сообщения, вы просто отказались от всего форматирования, которое я сделал –

ответ

2

Короткий ответ: если вы хотите, except блок для запуска, если вы получаете код состояния другого, то 0, то вызовет ошибку в method2:

if (status != 0) 
    log_exception() 
    raise RuntimeError("got non-0 exit code: %d"%status) 

Длинный ответ с примерами: она сильно зависит от того, как вы выполняете команду, os.system только возникает ошибка, если не дать ему str:

import os 
... #def method1 and method2 
execute_command = os.system 
method1() 

это назвали бы log_exception() так <some linux command> не правильная команда. Но ошибка не возникает, поэтому handle_exception() не будет использоваться. Вы можете также использовать subprocess.call:

import subprocess 
... #def method1 and method2 
execute_command = subprocess.call 
method1() 

subprocess.call Таким образом, возникает ошибку, когда он не может найти исполняемый файл под названием <some linux command>, но с действительным исполняемым и аварийным процессом:

import subprocess 

... #def method1 

def method2(): 
    command = ["python","-c","INVALID CODE !!"] 
    status = subprocess.call(command) 
    if(status !=0): 
     print("got non-0 status: %r"%status) 

method1() 

Этим путем были ошибка в вызове и возвращенный статус не-0, но это не вызывает никаких ошибок в python, если вы хотите, чтобы method2 поднимал ошибку python для статуса выхода без 0, это легко сделать:

+0

Спасибо. Меня заинтересовал последний пример, когда код во втором процессе вызвал исключение. Поэтому я считаю, что мое понимание было правильным, начиная с – madridista

+0

, используя ['execfile'] (https://docs.python.org/2/library/functions.html#execfile) _may_ вместо этого вместо команд python, поскольку он остается в той же трассе стек, но он совершенно другой, чем открытие подпроцесса. –

-1

Нет, это не будет, и трассировка не будет напечатана. На самом деле ничего не видно пользователю (если вы исправляете очевидные синтаксические ошибки).

+0

Это уже [было предложено] (http: // stackoverflow .com/questions/35802263/exception-percolation-in-linux-python/35802498 # comment59274201_35802263) и не очень [подходящий ответ] (http://stackoverflow.com/help/how-to-answer). –

+0

Это не было предложением, а фактическим ответом на предыдущую версию вопроса. Я почти уверен, что это, по крайней мере, верно для вопроса, поскольку оно было сформулировано в то время. Наверное, это не делает его подходящим. – Goyo

+0

вы не предоставляете контекст или объяснение; В каком случае ничего не будет видно пользователю? В исходной версии вопроса не было вызова метода 'method1', который не привел бы к выходу, но было довольно очевидно, что это не был исполняемый код copy-paste. Он также не выдавал никакого результата, если 'log_exception' и' handle_exception' не отображали информацию, но подразумевается, что они это делают. Так в каком случае ничего не увидит пользователь? –

Смежные вопросы