В приведенном ниже коде возникают два исключения: A ValueError
и специфичная для библиотеки ApplicationError
. ValueError
все еще выводится на консоль. Почему блок except
не подавляет свой вывод?
from pyomo.common.errors import ApplicationError
from pyomo.environ import SolverFactory
try:
solver = SolverFactory("glpk", executable = "bad_path")
if solver.available():
print("GLPK solver is available.")
else:
print("GLPK solver not available.")
except (ValueError, ApplicationError) as e:
# except Exception as e: # also doesn't work
print(f"Caught {type(e).__name__}")
Вывод консоли:
> python .\test_pyomo_glpk_solver.py
WARNING: Failed to create solver with name '_glpk_shell': Failed to set
executable for solver glpk. File with name=bad_path either does not exist or
it is not executable. To skip this validation, call set_executable with
validate=False.
Traceback (most recent call last):
File ".\env\Lib\site-packages\pyomo\opt\base\solvers.py", line 148, in __call__
opt = self._cls[_name](**kwds)
^^^^^^^^^^^^^^^^^^^^^^^^
File ".\env\Lib\site-packages\pyomo\solvers\plugins\solvers\GLPK.py", line 92, in __init__
SystemCallSolver.__init__(self, **kwargs)
File ".\env\Lib\site-packages\pyomo\opt\solver\shellcmd.py", line 66, in __init__
self.set_executable(name=executable, validate=validate)
File ".\env\Lib\site-packages\pyomo\opt\solver\shellcmd.py", line 115, in set_executable
raise ValueError(
ValueError: Failed to set executable for solver glpk. File with name=bad_path either does not exist or it is not executable. To skip this validation, call set_executable with validate=False.
Caught ApplicationError
Обратите внимание, что ваш код не отображается в трассировке, поэтому он не является источником этого кода.
@jonrsharpe, ошибка не фиксируется. Я могу повторить проблему.
...Да, это так. Вы достигаете print(msg)
в блоке except
. Пройдите через отладчик.
@Salvatore, оказывается, это logger.warning, показывающий исключение. Смотрите мой ответ, как его подавить.
Каковы доказательства того, что ApplicationError
повышен? Если первый WARNING
является доказательством, похоже, что-то еще улавливает и «обрабатывает» ошибку. Вам больше нечего ловить ApplicationError
.
@chepner Последняя строка вывода консоли — это сообщение об ошибке, выведенное из блока except
. Я отредактирую, чтобы было понятнее.
Вы не можете вызвать два исключения «одновременно»; первое исключение предотвращает запуск любого кода (включая тот, который может вызвать второе исключение). Выполнение не возобновляется до тех пор, пока не будет перехвачено первое исключение.
То, что вы видите, на самом деле не является всплывающей ошибкой, это logger.warning
, который уловил ошибку и показывает ее. См. строку здесь, в коде Pyomo
Вы можете подавить его, изменив уровень ведения журнала для этого модуля.
from pyomo.common.errors import ApplicationError
from pyomo.environ import SolverFactory
import logging
logger = logging.getLogger('pyomo.opt')
logger.setLevel(logging.ERROR)
try:
solver = SolverFactory("glpk", executable = "bad_path")
if solver.available():
print("GLPK solver is available.")
else:
print("GLPK solver not available.")
except ApplicationError as e:
print(f"Caught {type(e).__name__}: {e}")
Ох, отличный улов. «ПРЕДУПРЕЖДЕНИЕ» должно было меня предупредить, но я пропустил это, поскольку оно также печатает обычное содержимое исключения.
issubclass(ValueError, Exception)
, поэтомуexcept Exception:
должен это поймать: docs.python.org/3/library/Exceptions.html#Exception-hierarchy