Демонстрация проблемы
Сначала посмотрим визуально как выглядит проблема. Типичный вертикальный список, в котором потеряна запятая:
languages = [ "english", "russian", "italian" # Печалька. Такое иногда бывает. "spanish" ]
Если внимательно посмотреть, между строками «italian» и «spanish» пропущена запятая. Но при запуске такой программы ошибок не будет: Python просто склеит строки «italian» и «spanish», превратив наш список вот в это:
languages = [ "english", "russian", "italianspanish" ]
На практике такие опечатки встречатся не то чтобы очень часто — но к багам приводят знатным и долгоотлаживаемым.
Как бороться по-феншую
В соответствии феншуем, данный ряд проблем необходимо отсекать статическими анализаторами кода типа lint в рамках автобилда. Но тут есть неприятный нюанс — pylint по умолчанию не считает пример выше ошибочным. Следовательно, придется его долго и муторно настраивать, потому как есть много вполне корректного кода, где строки склеиваются по делу и никаких запятых быть не должно. Плюс не у всех настроена связка pylint + autobuild, а поднимать полноценный continous integration с нуля только ради указанной проблемы не всегда с руки.
Как борются на практике
На данный момент есть два популярных способа борьбы с этой проблемой. Первый заключается в том, чтобы оканчивать каждую строку запятой, включая последнюю, а терминатор списка писать на отдельной строке. Это позволяет в большинстве случаев избежать проблем при копипасте строк и удалении строк:
languages = [ "english", "russian", "italian", "spanish", # Если переместить этот элемент вверх, запятые не поломаются. ]
Минусом первого способа является то, что он защищает только от ошибок копипасты — но не защищает от опечаток и результатов применения к тексту скриптов.
Второй способ заключается в тактической установке запятых не после элементов, а перед ними. Это вытраивает красиву вертикальную черту, в которой пропуски видны невооруженным глазом:
languages = [ "english" , "russian" , "italian" , "spanish" ]
Недостатком данного способа является отсутствие защиты у первого элемента (если его куда-нибудь переместить, то будет потеря запятой) и некавайный непривычный внешний вид. Совсем непривычный.
Новый способ
Был подсказан гуру на stackoverflow. Не могу сказать что он особо красив или удобен — но он прост и надежен. При потере запятой случается ошибка выполнения скрипта. Способ заключется в окружении каждой строки круглыми скобками — это превращает epression типа строка в сложносоставной expression, который уже склеивать нельзя:
languages = [ ("english"), ("russian"), ("italian") # Теперь потерянная запятая - синтаксичекая ошибка. ("spanish") ]
Вот такое неожиданное решение. Надеюсь, послужит кому-нибудь источником вдохновения. Приятных выходных, коллеги 🙂
ссылка на оригинал статьи http://habrahabr.ru/company/radmin/blog/134080/
Добавить комментарий