Аварийный выход в Python без goto - PullRequest
2 голосов
/ 25 января 2012

В CI регулярно используйте goto, чтобы выпрыгнуть из середины функции и распутать все, что я сделал в функции, когда возникает исключение, которое не может быть обработано изящно;например, закройте файловые дескрипторы, освободите выделенную память, которая не будет использоваться, например,

error3:
    for(j=0; j<i; j++) {
        nameDelete(names[j]);
    }
error:2
    free(names);
error1:
    close(fd);
error0:
    exit(-1);

В начале кода перед открытием fd я выпрыгну с ошибкой 0:, позже с ошибкой 1: и таквперед, как я хватаю ресурсы.

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

Я не привязан к синтаксису goto (и я читал Dijkstra), однако мне интересно, есть ли общий шаблон для такого рода операций в Python.(Быстрый) обзор Python в двух словах не сильно помог.

[EDIT]

Чего я пытаюсь избежать, так это

try:
    foo1
except: 
    bar0
try: 
    foo2
except: 
    bar0
try: 
    foo3
except: 
    bar1
try:
    foo4
except:
    bar2

, где bar2 включает в себя все в bar2, которое включает в себя все в bar0.Я признаю, что большая часть того, что я делаю в баре #, вероятно, обрабатывается GC, но я предпочитаю быть педантичным, особенно при переносе кода (что я и делаю), прежде чем я сделаю его рефакторинг.

Ответы [ 4 ]

4 голосов
/ 25 января 2012

Python использует для этого систему исключений:

raise Exception("ERROR")

Это продолжит "распутывать" и очищать стек, пока исключение не получит , пойманный обработчиком исключения.Если исключение не было обнаружено, программа останавливается, печатает исключение и завершается.

Подробнее об исключениях можно узнать в официальном руководстве по Python .

Также вы описалииспользование ресурсов.Это делается чаще всего с помощью двух шаблонов:

  • инициализация и очистка, ресурс выделяется при инициализации и освобождается при освобождении (методы __init__ и __del__)
  • with оператор, (методы __enter__ и __exit__)

Оба шаблона будут корректно очищаться в случае исключения.

0 голосов
/ 25 января 2012

Наряду с исключениями оператор with часто используется, в частности, с файловыми дескрипторами.

http://effbot.org/zone/python-with-statement.htm

http://docs.python.org/reference/compound_stmts.html#the-with-statement

К вашему сведению, хотя это «плохая практика», файловые объекты закрываются, как только они получают GCed, что происходит, как только онивыйдите из области видимости, если у вас нет других ссылок на них.Так что на самом деле файл не останется открытым:

def _readfile():
    f = open("path")
    return f.read()

Но вы точно будете за это судить, если это ваше дело:)

0 голосов
/ 25 января 2012

Если вам нужно обработать ошибки, используйте исключения. Пример из официального руководства по Python:

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

Кстати, вы можете поднять свои собственные исключения, когда это необходимо.

0 голосов
/ 25 января 2012

Я не уверен, что полностью понимаю вашу потребность, но, похоже, вы можете использовать try ... except ... finally

Подробнее об исключениях и обработке исключений здесь: http://docs.python.org/tutorial/errors.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...