Правильный выход из цикла while при ошибке - PullRequest
1 голос
/ 23 августа 2011

Мне любопытно, каков «правильный» питонный способ обработки этой ошибки с помощью цикла while.Я мог бы просто проверить строку, чтобы увидеть, имеет ли она символ [-1] заранее в этом примере, но фактический код, на котором основан этот пример моей проблемы, гораздо сложнее.

try:
    while mystring[-1] == '!' #Will throw an error if mystring is a blank string
         print("Exclamation!")
         mystring = mystring[:-1]
    return mystring
except:
    return ""

Эффективно мойпроблема в том, что мой цикл while зависит от проверки, которая иногда после некоторой обработки в цикле выдает ошибку.Вышесказанное является лишь (возможно, чрезмерно) упрощенной иллюстрацией этой проблемы.Я исправил это с помощью серии try: excepts: s, но мне кажется, что это не «правильный» способ решения этой проблемы.

Ответы [ 3 ]

3 голосов
/ 23 августа 2011

Для вашего примера вы можете просто сделать что-то вроде:

while mystring and mystring[-1] == '!':
    print("Exclamation!")
    mystring = mystring[:-1]
return mystring

Это будет работать, потому что оно закоротит и завершит цикл, если mystring пуста, поэтому вы никогда не будете пытаться получить доступ к -1 индексу пустой строки

Редактировать: Как указал Уинстон, вы можете избавиться от всех специальных оболочек, используя str.endswith, как показано в следующем коде

while mystring.endswith('!'):
    print("Exclamation!")
    mystring = mystring[:-1]
return mystring
3 голосов
/ 23 августа 2011

Две вещи, которые ваш текущий код делает, что вы не должны делать:

  1. Ловит любое исключение, вы должны поймать только конкретное интересующее исключение
  2. Включает весь цикл в блок try, вам следует, если это возможно, включать только тот оператор / выражение, которое вызывает исключение

Если вы часто используете циклы while в python, это говорит о том, что вы не используете Python наиболее эффективно. Учитывая набор инструментов Python, вы почти всегда должны использовать какой-то цикл for. Не видя реального примера вашего кода, я не могу сказать, правда ли это. Если вам нужна помощь в этой области, напишите код на http://codereview.stackexchange.com

Общее решение этой проблемы - написать функцию, которая обрабатывает исключение, и использовать ее.

def last_character(string):
    try:
       return string[-1]
    except IndexError:
       return ' '

while last_character(mystring) == '!'
    mystring = mystring[:-1]
return mystring

Фактически, во многих случаях уже есть эквиваленты без исключений для стандартных конструкций. Этот цикл можно легко написать с помощью метода .endswith (). Используя их или создавая свои собственные, вы можете работать с исключениями наиболее аккуратно.

2 голосов
/ 23 августа 2011

Используйте mystring.rstrip('!') для удаления символов '!' в конце строки; -)

Если проблема намного сложнее, правильный способ - перехватить IndexError, выданный операцией.

try:
    while mystring[-1] == '!' #Will through an error if mystring is a blank string
         print("Exclamation!")
         mystring = mystring[:-1]
    return mystring
except IndexError:
    return ""

Другой способ - проверить строку на пустоту и избежать использования операции, которая вызывает исключение:

while mystring and mystring[-1] == '!': # lazy boolean expression evaluation
      mystring = mystring[:-1]
return mystring

Другая версия без вычисления ленивых логических выражений:

if not mystring:
    return mystring
while mystring[-1] == '!':
    mystring = mystring[:-1]
    if not mystring:
        break
return mystring

Я лично предпочитаю вторую версию, особенно если вы меняете mystring [-1] == '!'с mystring.endswith ('!') (но в этом случае вам не нужно проверять на пустоту, потому что конец с уже делает это за вас).

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