Функция main() для Python
Перевод: Орехов А.И. Истчоник: www.python.ru
Перевод статьи Гвидо ван Россума, рассказывающей о том, как следует оформлять функцию main().
Хочу предложить программистам функцию main(), которую удобно использовать в различном контексте. Например в интерактивном режиме Python, когда вам хочется поэкспериментировать.
В свое время, я определял функцию main() различным образом. Приблизительно так:
"""Описание модуля. Подробное описание использования. """ import sys import getopt def main(): # Разбираем аргументы командной строки try: opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) except getopt.error, msg: print msg print "для справки используйте --help" sys.exit(2) # process options for o, a in opts: if o in ("-h", "--help"): print __doc__ sys.exit(0) # Анализируем for arg in args: process(arg) # process() определен в другом месте if __name__ == "__main__": main()
Я уверен, что многие пишут нечто подобное main() функции. Несколько предложений, которые сделают эту функцию более гибкой. Тем более, что синтаксический анализ опций становится все более сложным.
Во первых, добавим дополнительный аргумент argv. Так, чтобы можно было вызывать функцию в интерактивном режиме:
def main(argv=None): if argv is None: argv = sys.argv # и т.д. заменяя sys.argv на argv в getopt запросах
Обратите внимание, что мы заполняем значения по умолчанию динамически. Это более гибко, чем:
def main(argv=sys.argv): # и т.д.
Таким образом теперь мы можем изменить параметры вызова в любой момент времени.
Вызов sys.exit() закрывает сессию интерпретатора. Доработаем программу:
if __name__ == "__main__": sys.exit(main())
Вызов sys.exit(main()) вернет результат функции.
Другое усовершенствование касается использования исключения Usage(), которое мы перехватываем в main:
import sys import getopt class Usage(Exception): def __init__(self, msg): self.msg = msg def main(argv=None): if argv is None: argv = sys.argv try: try: opts, args = getopt.getopt(argv[1:], "h", ["help"]) except getopt.error, msg: raise Usage(msg) # more code, unchanged except Usage, err: print >>sys.stderr, err.msg print >>sys.stderr, "for help use --help" return 2 if __name__ == "__main__": sys.exit(main())
Теперь мы имеем единственную точку выхода из функции, что предпочтительнее множественных return 2. Это также облегчает повторный анализ параметров: raise Usage вызывается просто во вспомогательной функции.
Вы можете возразить, что можно перенести конструкцию try/except из main() в конец модуля (if __name__ == "__main__": ...). Но это привело бы к возникновению ошибки при вызове в интерактивном режиме интерпретатора.
Однако, обобщение может быть полезным: определите другое исключение (возможно Error), которое обрабатывается так же, как и Usage, но возвращает 1. Его можно применять для ожидаемых ошибок типа отказа открыть необходимые файлы. Не ситаксические ошибки командной строки, но ожидаемые ситуации. Т.к. traceback не очень дружественное средство в таких случаях.
Оставить комментарий
Комментарии


Вообще, автор не большой спец в преподавании. Его метод: вот тебе Пример, а общие выводы делай сам...