2015-04-24 2 views
0

У меня есть функция, которая выглядит для специальных Element, если файлы проекта:перехватывать исключение с подъемным

def csproj_tag_finder(mod_proj_file): 

    """Looking for 'BuildType' element in each module's csproj file passed in `mod_proj_file` 
     ard return it's value (CLOUD, MAIN, NGUI, NONE)""" 

    try: 
     tree = ET.ElementTree(file=mod_proj_file) 
     root = tree.getroot() 


     for element in root.iterfind('.//'): 
      if ('BuildType') in element.tag: 
       return element.text 

    except IOError as e: 
#  print 'WARNING: cant find file: %s' % e 

Если файл не найден - он печатает 'WARNING: cant find file: %s' % e.

Эта функция вызывается из другого:

def parser(modename, mod_proj_file): 
     ... 
     # module's tag's from project file in <BuildType> elements, looks like CLOUD 
     mod_tag_from_csproj = csproj_tag_finder(mod_proj_file) 
     if not mod_tag_from_csproj: 
      print('WARNING: module %s have not <BuildType> elements in file %s!' % (modename, mod_proj_file)) 
     ... 

Так что - если файл не найден - csproj_tag_finder() возврат None тип и печать WARNING. Вторая функция - parser() найти пустой mod_tag_from_csproj переменная, а также печать WARNING. Это безобидно, поэтому я хочу сделать csproj_tag_finder() поднять специальный Exception, так parser() за исключением этого и пройти == проверить, а не печатать текст.

Я пытался добавить что-то вроде:

... 
    except IOError as e: 
#  print 'WARNING: cant find file: %s' % e 
     raise Exception('NoFile') 

к csproj_tag_finder(), чтобы поймать его позже в parser() - но это немедленно прервать дальнейшие шаги.

P.S. Позже if not mod_tag_from_csproj: вызовет еще одну функцию, чтобы добавить новый Element. Эта задача может быть решена только с return 'NoFile', а затем поймать с if/else - но мне кажется, что raise будет более правильным способом здесь. Или нет?

ответ

1

raise Прерывание следующих шагов сразу - это именно то, что он должен делать. На самом деле, это целая точка исключений.

return Но также прерывает следующие шаги немедленно, потому что возвращение рано и весь смысл return.

Если вы хотите сохранить ошибку до конца, продолжайте выполнять другую работу, а затем поднимите ее в конце, вы должны сделать это явно. Например:

def spam(): 
    error = None 
    try: 
     do_some_stuff() 
    except IOError as e: 
     print 'WARNING: cant find file %s' % e 
     error = Exception('NoFile') 
    try: 
     do_some_more_stuff() 
    except OtherError as e: 
     print 'WARNING: cant frob the glotz %s' % e 
     error = Exception('NoGlotz') 
    # etc. 
    if error: 
     raise error 

Теперь, пока нет непредвиденного исключения, что вы забыли обработать, что бы не удалось в прошлом будет error, и он будет поднят в конце.


Как примечание стороны, вместо того, чтобы поднимать Exception('NoFile'), а затем с помощью ==, чтобы проверить строку исключений позже, вы, вероятно, хотите создать подкласс NoFileException; то вам не нужно тестировать его, вы можете просто обработать его с помощью except NoFileException:. А это означает, что вы можете нести другую полезную информацию (фактическое исключение, имя файла и т. Д.) В своем исключении, даже если это не мешает. Если это звучит страшно для реализации, это не так. Это буквально однострочный:

class NoFileException(Exception): pass 
Смежные вопросы