Как использовать sys.exit (0) в скрипте arcpy для раннего выхода без отображения сообщения об ошибке?

13

У меня есть скрипт инструмента arcpy для ArcGIS 10.0, который имеет два основных функциональных раздела. Пользователь может выбрать, следует ли запускать второй раздел. Если пользователь выбирает НЕ запускать второй раздел, я просто хочу запустить функцию очистки и выйти из сценария с помощью sys.exit (0), не отправляя сообщение об ошибке в окно результатов инструмента. Здесь, в GIS-SE, есть два основных потока о выходе из скриптов arcpy, но решения в них специально не обращаются к сообщению об ошибке. Общая структура кода выглядит следующим образом:

import sys
##import arcpy

def CleanUp():
    print 'Cleaning up ...\n'

def finish():
    CleanUp()
    print 'Exiting ...'
    sys.exit(0)

do_more = False  #or True ... input from user

#Section 1:  do some stuff
print 'Doing some stuff ...\n'

if not do_more:
    finish()

#Section 2:  do more stuff
print 'doing more stuff ...'
CleanUp()

Если я запускаю этот код в интерпретаторе Python за пределами ArcGIS / arcpy, он работает, как и ожидалось, изящно завершается без сообщения об ошибке; однако в моем скрипте arcpy с такой же структурой скрипт завершается, но сообщение об ошибке SystemExit отправляется в окно результатов инструмента. Есть ли способ заставить скрипт инструмента arcpy съесть исключение и скрыть сообщение об ошибке SystemExit?

celticflute
источник
Просто сделайте дикий удар здесь, но возможно ли, что вы могли бы "del arcpy" перед вызовом SystemExit в вашем скрипте?
@ Дэн - я сомневаюсь в этом, но это интересная идея ... хммм ... какого черта. Я поверну это.
celticflute
1
Благодарим Вас за публикацию краткого примера кода, который ясно иллюстрирует логику и не учитывает дополнительных возможностей. +1
Мэтт Уилки

Ответы:

8

Краткий ответ: исправлено в 10.1. На данный момент вам нужно добавить дополнительный уровень отступа. Это может способствовать некоторому полезному рефакторингу вашего кода. Каждый раз, когда вы получаете большое количество строк в одном скрипте / подпрограмме, вы все равно должны подумать о том, чтобы разрезать его на более мелкие разделы (функции, классы).

def main():
    <your code>

if __name__ == "__main__":
    try:
        main()
    except SystemExit as err:
        pass
Джейсон Шайрер
источник
Спасибо Джейсон. Да, я должен укусить пулю и рефакторинг. Это просто трудно сделать, когда клиент дышит мне в шею. Такова жизнь.
celticflute
3

ArcPy портит вашу среду Python . Короче говоря, либо не выполняйте sys.exit (), ни находите / вызывайте функцию arcpy «cleanup-before-exit» (если она существует) перед вызовом sys.exit ().

Говард Батлер
источник
2
То, как исполняемые дескрипторы Python sys.exit()являются своего рода подвохом - вызов exitвызывает SystemExitисключение, и интерпретатор верхнего уровня, который обычно печатает трассировку, обнаружит тип исключения и завершит работу интерпретатора. Встраивание интерпретатора Python в другое приложение, такое как исполняемые файлы семейства ArcGIS, требует нетривиального количества кода, специфичного для реализации, такого как этот.
Джейсон Шайрер,
2

Я не знаю, как «похоронить» сообщение об ошибке SystemExit, но вы всегда можете реструктурировать свой код, чтобы избежать вызова sys.exit

import sys
##import arcpy

def DoMoreStuff():
    print 'doing more stuff ...'

def CleanUp():
    print 'Cleaning up ...'

def finish():
    CleanUp()
    print 'Exiting ...'

do_more = False  #or True ... input from user

#Section 1:  do some stuff
print 'Doing some stuff ...'

if do_more:DoMoreStuff()

finish()
user2856
источник
Правда, но два раздела в моем arcpy скрипте довольно большие. Я бы предпочел не создавать еще один уровень отступов, и мне пришлось бы решать возникающие проблемы ... но, да, это было бы решением. Что действительно расстраивает, так это то, что сообщение об ошибке появляется только при использовании sys.exit в arcpy. В обычном Python сообщение не публикуется, поскольку исключение SystemExit не считается ошибкой.
celticflute