Используйте assert для потока управления

Я пытаюсь проверить, есть ли в конце слова точка с запятой. У меня есть позиция слова в длинной строке, и я хочу проверить, если символ в позиции start of word + length of word это :, Возможно, это слово является последним словом в строке, и поэтому попытка получить следующий символ вызовет IndexException

У меня есть три идеи:

1) Убедитесь, что мы не в конце строки, а затем убедитесь, что это не точка с запятой

semicolon_pos = pos_word + len(word) # Possible position
if semicolon_pos < len(long_string) and long_string[semicolon_pos] == ':':
    # do something...
else:
    # do something else

Не то, что обычно считается питоническим

2) Попробуйте - кроме извлечения точки с запятой и равенства для точки с запятой

semicolon_pos = pos_word + len(word) # Possible position
try:
   if long_string[semicolon_pos] == ':':
      # Do something
   else:
      # do something else (which is the same as in the except clause)

except IndexError:
    # do something else

Выглядит немного странно, чтобы извлечь, а затем вложенный. И я должен сделать небольшой трюк, чтобы избежать дублирования кода

3) Попробуйте - за исключением извлечения точки с запятой и утверждения, чтобы убедиться, что это точка с запятой

semicolon_pos = pos_word + len(word) # Possible position
try:
    assert long_string[semicolon_pos] == ':'
    # do something
except (IndexError, AssertionError):
    # do something else

Структура более плоская и легко читаемая, но у меня такое ощущение, что злоупотребляют исключениями.

Что говорят питонцы? заранее спасибо.

4 ответа

Решение

Самый простой способ - просто использовать срез в качестве индекса. Срезы не генерируют IndexError:

semicolon_pos = pos_word + len(word) # Possible position
if long_string[semicolon_pos:semicolon_pos+1] == ':':
   # Do something
else:
   # do something else 

Определенно неправильное использование утверждений. Причина: утверждения даже не выполняются, когда код запускается с -O флаг.

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

(string[index] if index < len(string) else None) == ':'

Я думаю, что так проще

#considering mylongstring contains the word
#+1 for the possible colon
mylongstring[:pos_word + len(word) + 1].endswith(':')

Или, если длинная строка очень длинная, вы не хотите копировать слишком много:

mylongstring[pos_word:pos_word + len(word) + 1][-1] == ':'
Другие вопросы по тегам