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

Python: использование различий и предложений sys.exit или SystemExit

Чтение онлайн-программистов использует sys.exit, другие используют SystemExit.
Извините за основной вопрос:

  • В чем разница?
  • Когда мне нужно использовать SystemExit или sys.exit внутри функции?

Пример

ref = osgeo.ogr.Open(reference)
if ref is None:
    raise SystemExit('Unable to open %s' % reference)

или

ref = osgeo.ogr.Open(reference)
if ref is None:
    print('Unable to open %s' % reference)
    sys.exit(-1)
4b9b3361

Ответ 1

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

Ответ 2

sys.exit(s) является просто сокращением для raise SystemExit(s), как описано в предыдущей документации; попробуйте help(sys.exit). Итак, вместо одной из ваших примерных программ вы можете сделать

sys.exit('Unable to open %s' % reference)

Ответ 3

Есть 3 функции выхода, помимо повышения SystemExit.

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

sys.exit определяется в sysmodule.c и просто запускается PyErr_SetObject(PyExc_SystemExit, exit_code);, что фактически совпадает с прямым повышением SystemExit. В мельчайших деталях повышение SystemExit возможно быстрее, поскольку sys.exit требует опций LOAD_ATTR и CALL_FUNCTION vs RAISE_VARARGS. Кроме того, raise SystemExit создает немного меньший байт-код (на 4 байта), (1 байт дополнительно, если вы используете from sys import exit, поскольку ожидается, что sys.exit возвращает None, поэтому включает дополнительный POP_TOP).

Последняя функция выхода определена в site.py и с псевдонимом exit или quit в REPL. Это фактически экземпляр класса Quitter (поэтому он может иметь пользовательский __repr__, поэтому, вероятно, это самый медленный запуск. Кроме того, он закрывает sys.stdin до повышения SystemExit, поэтому он рекомендуется использовать только в REPL.

Что касается обработки SystemExit, это в конечном итоге приводит к тому, что виртуальная машина вызывает os._exit, но до этого она выполняет некоторую очистку. Он также запускает atexit._run_exitfuncs(), который выполняет любые обратные вызовы, зарегистрированные через модуль atexit. Вызов os._exit напрямую обходит шаг atexit.

Ответ 4

Мои личные предпочтения заключаются в том, что по крайней мере SystemExit поднимается (или даже лучше - более значимое и хорошо документированное пользовательское исключение), а затем оказывается как можно ближе к основной функции, которая может иметь последний шанс считать его действительным выходом или нет. Библиотеки/глубоко внедренные функции, имеющие sys.exit, просто противны с дизайнерской точки зрения. (Как правило, выход должен быть "как можно выше" )

Ответ 5

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

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

Ответ 6

В соответствии с документацией sys.exit(s) эффективно делает raise SystemExit(s), так что это почти то же самое.

Ответ 7

Как вы можете прочитать здесь: Разница между exit() и sys.exit() в Python sys.exit(...) выполняет некоторую очистку и очищает буферы stdio, а после очистки очищает SysExit

если вы хотите напечатать сообщение об ошибке, вы можете просто сказать: "sys.exit(" сообщение об ошибке ") вместо того, чтобы делать печать раньше и" сообщение об ошибке "будет напрямую перейти к stderr вместо stdout, такое же поведение, как" raise SysError ( "сообщение об ошибке" )".

Таким образом, если вы хотите выйти, вы должны предпочесть sys.exit только для повышения SysExit, sys.exit(...) можно поймать так же, как только повышение SysExit и sys.exit(0) больше читаемый, чем "поднять SysExit", на мой взгляд.