2016-11-03 5 views
2

Существует определенная проблема, с которой я столкнулся с обработкой исключений в Python. Было много ситуаций, когда есть область кода, где я хочу, чтобы все исключения игнорировались. Скажем, у меня есть 100 строк кода, где я хочу, чтобы это произошло.Обработка исключений в Python

Это то, что большинство будет думать, будет решение:

try: 
    line 1 
    line 2 
    line 3 
    ... 
    line 99 
    line 100 
except: 
    pass 

Это на самом деле не работает в моей ситуации (и во многих других ситуациях). Предположим, что в строке 3 есть исключение. Когда исключение выбрасывается, оно переходит прямо к «pass» и пропускает строки 4-100. Единственное решение, я смог придумать это:

try: 
    line 1 
except: 
    pass 

try: 
    line 2 
except: 
    pass 

try: 
    line 3 
except: 
    pass 

... 

try: 
    line 99 
except: 
    pass 

try: 
    line 100 
except: 
    pass 

Но, как видно, это очень некрасиво, неаккуратно, и принимает абсолютно навсегда. Как я могу сделать вышеуказанный код короче, чище? Бонусные баллы, если вы даете метод, позволяющий заменить «pass» другим кодом.

+7

Похоже, вам нужно сделать серьезный пересмотр кода. У вас действительно есть 100 полностью независимых строк кода, которые вообще не зависят друг от друга и не могут быть помещены в цикл, что все может потерпеть неудачу в том, как ваш код может восстановиться? –

+0

, если вы проводите тесты, вы действительно должны иметь инкрементные тесты в любом случае ... Так например .... если рабочий поток a-> b-> c, для выполнения c, ему необходимо сначала выполнить a-> b .... так что если a или b терпят неудачу, не было бы причин для проверки на c. – Fallenreaper

+0

У меня на самом деле нет 100 строк, у меня иногда есть 6 или 7. Даже с 6 или 7, это все еще очень неряшливо. – Douglas

ответ

3

Как и другие ответы уже говорилось, вы должны рассмотреть вопрос рефакторинга кода.

Таким образом, я не мог удержаться от того, чтобы не взломать что-то вместе, чтобы иметь возможность выполнять вашу функцию без сбоев и вырывов в случае возникновения исключения.

import ast, _ast, compiler 

def fail(): 
    print "Hello, World!" 
    raise Exception 
    x = [4, 5] 
    print x 

if __name__ == '__main__': 
    with open(__file__, 'r') as source: 
     tree = ast.parse(source.read(), __file__) 
     for node in ast.iter_child_nodes(tree): 
      if isinstance(node, _ast.FunctionDef): 
       _locals = {} 
       for line in node.body: 
        mod = ast.Module() 
        mod.body = [line] 
        try: 
         exec(compile(mod, filename='<ast>', mode='exec'), _locals, globals()) 
        except: 
         import traceback 
         traceback.print_exc() 

код выполняет какую-либо функцию он находит в глобальном масштабе, и предотвращает его от выхода в случае, если он терпит неудачу. Он делает это, итерируя по AST файл и создавая новый модуль для выполнения для каждой строки функции.

Как и следовало ожидать, выход программы:

Hello, World! 
Traceback (most recent call last): 
    File "kek.py", line 18, in <module> 
    exec(compile(m, filename='<ast>', mode='exec'), _locals, globals()) 
    File "<ast>", line 3, in <module> 
Exception 
[4, 5] 

Я хотел бы подчеркнуть, что использование этого в любом производстве кода является плохой идеей. Но ради аргумента, что-то вроде этого будет работать. Вы могли бы даже обернуть его красивым декоратором, хотя это ничего не сделало бы с тем, что это плохая идея .

Счастливый рефакторинг!

+0

Хотя это не тот ответ, который мне нужен, он все равно отвечает на мой вопрос. Я, вероятно, просто придерживаюсь старого способа (это всего лишь несколько строк кода, а не 100), потому что это производственный код. Весь мой код не такой неряшливый, но есть места, где вещи становятся супер сложными и беспорядочными. – Douglas

0

Вы можете попытаться сломать код на более мелкие куски, чтобы он мог правильно обрабатывать ошибки, а не требовать отказа от всех прогрессов и обратной связи.

Другое решение, которое может быть использовано в дополнение к этому, - это делать проверки, если установлены флаги для вашего кода, чтобы проверить, может ли он действовать, или если необходимо повторить последний шаг, вы сможете предотвратить дополнительные итерации.

Пример:

while not continue: 
    try: 
     a = input('Enter data') 
    except: 
     pass 
    if a != null: 
     continue = true 
Смежные вопросы