Подтвердить что ты не робот

Python: выбор конкретного исключения

Я хочу поймать определенный ValueError, а не только любой ValueError.
Я пробовал что-то вроде этого:

try: maquina['WPF'] = macdat(ibus, id, 'WPF')
except: ValueError, 'For STRING = ’WPF’, this machine is not a wind machine.':
    pass

Но он вызывает SyntaxError: не может назначить литерал.
Затем я попробовал:

try: maquina['WPF'] = macdat(ibus, id, 'WPF')
except ValueError, e:
    if e != 'For STRING = ’WPF’, this machine is not a wind machine.':
        raise ValueError, e

Но это вызывает исключение, даже если это то, чего я хочу избежать.

4b9b3361

Ответ 1

in except ValueError,e, e - это экземпляр исключения, а не строка. Поэтому, когда вы проверяете, не соответствует ли e конкретной строке, этот тест всегда False. Попробуйте:

if str(e) != "..."

вместо.

Пример:

def catch(msg):
    try:
        raise ValueError(msg)
    except ValueError as e:  # as e syntax added in ~python2.5
        if str(e) != "foo":
            raise
        else:
            print("caught!")

catch("foo")
catch("bar")

Как правило, вы действительно не хотите полагаться на сообщение об ошибке, если сможете это сделать - это слишком хрупко. Если вы управляете вызываемым macdat, вместо повышения ValueError в macdat, вы можете создать настраиваемое исключение, которое наследует от ValueError:

class MyValueError(ValueError): pass

Тогда вы можете только поймать MyValueError и позволить другим ValueError продолжать свой путь, чтобы быть пойманным чем-то другим (или нет). Простой except ValueError по-прежнему будет захватывать этот тип исключения, поэтому он должен вести себя одинаково в другом коде, который также может захватывать ValueErrors из этой функции.

Ответ 2

Метод для последнего правильный (но напечатайте repr (e), чтобы понять, почему он не работает).

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

Для этого используйте рейз без аргумента (конечно, в пределах исключающего блока, иначе нет "текущего" исключения).