Перейти к содержимому

Inconsistent use of tabs and spaces in indentation python что это

  • автор:

Неверный синтаксис в Python: общие причины SyntaxError

Неверный синтаксис в Python: общие причины SyntaxError

Python известен своим простым синтаксисом. Однако, когда вы изучаете Python в первый раз или когда вы попали на Python с большим опытом работы на другом языке программирования, вы можете столкнуться с некоторыми вещами, которые Python не позволяет. Если вы когда-либо получали + SyntaxError + при попытке запустить код Python, то это руководство может вам помочь. В этом руководстве вы увидите общие примеры неправильного синтаксиса в Python и узнаете, как решить эту проблему.

Неверный синтаксис в Python

Когда вы запускаете ваш код Python, интерпретатор сначала анализирует его, чтобы преобразовать в байтовый код Python, который он затем выполнит. Интерпретатор найдет любой недопустимый синтаксис в Python на этом первом этапе выполнения программы, также известном как этап синтаксического анализа . Если интерпретатор не может успешно проанализировать ваш код Python, это означает, что вы использовали неверный синтаксис где-то в вашем коде. Переводчик попытается показать вам, где произошла эта ошибка.

Когда вы изучаете Python в первый раз, может быть неприятно получить + SyntaxError + . Python попытается помочь вам определить, где в вашем коде указан неверный синтаксис, но предоставляемый им traceback может немного сбить с толку. Иногда код, на который он указывает, вполне подходит.

Вы не можете обрабатывать неправильный синтаксис в Python, как и другие исключения. Даже если вы попытаетесь обернуть блок + try + и + кроме + вокруг кода с неверным синтаксисом, вы все равно увидите, что интерпретатор вызовет + SyntaxError + .

+ SyntaxError + Исключение и трассировка

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

Вы можете увидеть недопустимый синтаксис в литерале словаря в строке 4. Во второй записи + ‘jim’ + пропущена запятая. Если вы попытаетесь запустить этот код как есть, вы получите следующую трассировку:

Обратите внимание, что сообщение трассировки обнаруживает ошибку в строке 5, а не в строке 4. Интерпретатор Python пытается указать, где находится неправильный синтаксис. Тем не менее, он может только указать, где он впервые заметил проблему. Когда вы получите трассировку + SyntaxError + и код, на который указывает трассировка, выглядит нормально, тогда вы захотите начать движение назад по коду, пока не сможете определить, что не так.

В приведенном выше примере нет проблемы с запятой, в зависимости от того, что следует после нее. Например, нет проблемы с отсутствующей запятой после + ‘michael’ + в строке 5. Но как только переводчик сталкивается с чем-то, что не имеет смысла, он может лишь указать вам на первое, что он обнаружил, что он не может понять.

Существует несколько элементов трассировки + SyntaxError + , которые могут помочь вам определить, где в вашем коде содержится неверный синтаксис:

Имя файла , где встречается неверный синтаксис

Номер строки и воспроизводимая строка кода, где возникла проблема

Знак ( + ^ + ) в строке ниже воспроизводимого кода, который показывает точку в коде, которая имеет проблему

Сообщение об ошибке , которое следует за типом исключения + SyntaxError + , которое может предоставить информацию, которая поможет вам определить проблему

В приведенном выше примере имя файла было + theofficefacts.py + , номер строки был 5, а каретка указывала на закрывающую кавычку из словарного ключа + michael + . Трассировка + SyntaxError + может не указывать на реальную проблему, но она будет указывать на первое место, где интерпретатор не может понять синтаксис.

Есть два других исключения, которые вы можете увидеть в Python. Они эквивалентны + SyntaxError + , но имеют разные имена:

Оба эти исключения наследуются от класса + SyntaxError + , но это особые случаи, когда речь идет об отступе. + IndentationError + возникает, когда уровни отступа вашего кода не совпадают. + TabError + возникает, когда ваш код использует и табуляцию, и пробелы в одном файле. Вы познакомитесь с этими исключениями более подробно в следующем разделе.

Общие проблемы с синтаксисом

Когда вы впервые сталкиваетесь с + SyntaxError + , полезно знать, почему возникла проблема и что вы можете сделать, чтобы исправить неверный синтаксис в вашем коде Python. В следующих разделах вы увидите некоторые из наиболее распространенных причин, по которым может быть вызвано «+ SyntaxError +», и способы их устранения.

Неправильное использование оператора присваивания ( + = + )

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

Первый пример пытается присвоить значение + 5 + вызову + len () + . Сообщение + SyntaxError + очень полезно в этом случае. Он говорит вам, что вы не можете присвоить значение вызову функции.

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

Вероятно, ваше намерение не состоит в том, чтобы присвоить значение литералу или вызову функции. Например, это может произойти, если вы случайно пропустите дополнительный знак равенства ( + = + ), что превратит назначение в сравнение. Сравнение, как вы можете видеть ниже, будет правильным:

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

Неправильное написание, отсутствие или неправильное использование ключевых слов Python

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

Существует три распространенных способа ошибочного использования ключевых слов:

Неправильное написание ключевое слово

Отсутствует ключевое слово

Неправильное использование ключевого слова

Если вы неправильно написали ключевое слово в своем коде Python, вы получите + SyntaxError + . Например, вот что происходит, если вы пишете ключевое слово + for + неправильно:

Сообщение читается как + SyntaxError: неверный синтаксис + , но это не очень полезно. Трассировка указывает на первое место, где Python может обнаружить, что что-то не так. Чтобы исправить эту ошибку, убедитесь, что все ваши ключевые слова Python написаны правильно.

Другая распространенная проблема с ключевыми словами — это когда вы вообще их пропускаете:

Еще раз, сообщение об исключении не очень полезно, но трассировка действительно пытается указать вам правильное направление. Если вы отойдете от каретки, то увидите, что ключевое слово + in + отсутствует в синтаксисе цикла + for + .

Вы также можете неправильно использовать защищенное ключевое слово Python. Помните, что ключевые слова разрешено использовать только в определенных ситуациях. Если вы используете их неправильно, у вас будет неправильный синтаксис в коде Python. Типичным примером этого является использование https://realpython.com/python-for-loop/#the-break-and-continue-statements [ + continue + или + break + ] вне цикла. Это может легко произойти во время разработки, когда вы реализуете вещи и когда-то перемещаете логику за пределы цикла:

Здесь Python отлично говорит, что именно не так. Сообщения » ‘break’ вне цикла » и » ‘continue’ не в цикле должным образом » помогут вам точно определить, что делать. Если бы этот код был в файле, то Python также имел бы курсор, указывающий прямо на неправильно использованное ключевое слово.

Другой пример — если вы пытаетесь назначить ключевое слово Python переменной или использовать ключевое слово для определения функции:

Когда вы пытаетесь присвоить значение + pass + , или когда вы пытаетесь определить новую функцию с именем + pass + , вы получите ` + SyntaxError + и снова увидеть сообщение + «неверный синтаксис» + `.

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

Список защищенных ключевых слов менялся с каждой новой версией Python. Например, в Python 3.6 вы можете использовать + await + в качестве имени переменной или имени функции, но в Python 3.7 это слово было добавлено в список ключевых слов. Теперь, если вы попытаетесь использовать + await + в качестве имени переменной или функции, это вызовет + SyntaxError + , если ваш код для Python 3.7 или более поздней версии.

Другим примером этого является + print + , который отличается в Python 2 от Python 3:

+ print + — это ключевое слово в Python 2, поэтому вы не можете присвоить ему значение. Однако в Python 3 это встроенная функция, которой можно присваивать значения.

Вы можете запустить следующий код, чтобы увидеть список ключевых слов в любой версии Python, которую вы используете:

+ keyword + также предоставляет полезную + keyword.iskeyword () + . Если вам просто нужен быстрый способ проверить переменную + pass + , то вы можете использовать следующую однострочную строку:

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

Отсутствующие скобки, скобки и цитаты

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

Здесь трассировка указывает на неверный код, где после закрывающей одинарной кавычки стоит + t ‘+ . Чтобы это исправить, вы можете сделать одно из двух изменений:

Escape одиночная кавычка с обратной косой чертой ( + ‘don \’ t ‘+ )

Окружить всю строку в двойных кавычках ( » не » )

Другая распространенная ошибка — забыть закрыть строку. Как для строк с двойными, так и с одинарными кавычками ситуация и обратная трассировка одинаковы:

Здесь, ссылка на словарь + ages + внутри напечатанной f-строки пропускает закрывающую двойную кавычку из ссылки на ключ. Итоговая трассировка выглядит следующим образом:

Python идентифицирует проблему и сообщает, что она существует внутри f-строки. Сообщение » неопределенная строка » также указывает на проблему. Каретка в этом случае указывает только на начало струны.

Это может быть не так полезно, как когда каретка указывает на проблемную область струны, но она сужает область поиска. Где-то внутри этой f-строки есть неопределенная строка. Вы просто должны узнать где. Чтобы решить эту проблему, убедитесь, что присутствуют все внутренние кавычки и скобки f-строки.

Ситуация в основном отсутствует в скобках и скобках. Например, если вы исключите закрывающую квадратную скобку из списка, Python обнаружит это и укажет на это. Однако есть несколько вариантов этого. Первый — оставить закрывающую скобку вне списка:

Когда вы запустите этот код, вам скажут, что есть проблема с вызовом + print () + :

Здесь происходит то, что Python думает, что список содержит три элемента: + 1 + , + 2 + и +3 print (foo ()) + . Python использует whitespace для логической группировки вещей, и потому что нет запятой или скобки, отделяющей + 3 + от `+ print (foo ()) + `, Python объединяет их вместе как третий элемент списка.

Еще один вариант — добавить запятую после последнего элемента в списке, оставляя при этом закрывающую квадратную скобку:

Теперь вы получаете другую трассировку:

В предыдущем примере + 3 + и + print (foo ()) + были объединены в один элемент, но здесь вы видите запятую, разделяющую два. Теперь вызов + print (foo ()) + добавляется в качестве четвертого элемента списка, и Python достигает конца файла без закрывающей скобки. В трассировке говорится, что Python дошел до конца файла (EOF), но ожидал чего-то другого.

В этом примере Python ожидал закрывающую скобку ( +] + ), но повторяющаяся строка и каретка не очень помогают. Отсутствующие круглые скобки и скобки сложно определить Python. Иногда единственное, что вы можете сделать, это начать с каретки и двигаться назад, пока вы не сможете определить, чего не хватает или что нет.

Ошибочный синтаксис словаря

Вы видели ссылку: # syntaxerror-exception-and-traceback [ранее], чтобы вы могли получить + SyntaxError + , если не указывать запятую в словарном элементе. Другая форма недопустимого синтаксиса в словарях Python — это использование знака равенства ( + = + ) для разделения ключей и значений вместо двоеточия:

Еще раз, это сообщение об ошибке не очень полезно. Повторная линия и каретка, однако, очень полезны! Они указывают прямо на характер проблемы.

Этот тип проблемы распространен, если вы путаете синтаксис Python с синтаксисом других языков программирования. Вы также увидите это, если перепутаете определение словаря с вызовом + dict () + . Чтобы это исправить, вы можете заменить знак равенства двоеточием. Вы также можете переключиться на использование + dict () + :

Вы можете использовать + dict () + для определения словаря, если этот синтаксис более полезен.

Использование неправильного отступа

Существует два подкласса + SyntaxError + , которые конкретно занимаются проблемами отступов:

В то время как другие языки программирования используют фигурные скобки для обозначения блоков кода, Python использует whitespace. Это означает, что Python ожидает, что пробелы в вашем коде будут вести себя предсказуемо. Он вызовет + IndentationError + , если в блоке кода есть строка с неправильным количеством пробелов:

Это может быть сложно увидеть, но в строке 5 есть только два пробела с отступом. Он должен соответствовать выражению цикла + for + , которое на 4 пробела больше. К счастью, Python может легко определить это и быстро расскажет вам, в чем проблема.

Здесь также есть некоторая двусмысленность. Является ли строка + print (‘done’) + after циклом + for + или inside блоком цикла + for + ? Когда вы запустите приведенный выше код, вы увидите следующую ошибку:

Хотя трассировка выглядит во многом как трассировка + SyntaxError + , на самом деле это + IndentationError + . Сообщение об ошибке также очень полезно. Он говорит вам, что уровень отступа строки не соответствует ни одному другому уровню отступа. Другими словами, + print (‘done’) + это отступ с двумя пробелами, но Python не может найти любую другую строку кода, соответствующую этому уровню отступа. Вы можете быстро это исправить, убедившись, что код соответствует ожидаемому уровню отступа.

Другой тип + SyntaxError + — это + TabError + , который вы будете видеть всякий раз, когда есть строка, содержащая либо табуляцию, либо пробелы для отступа, в то время как остальная часть файла содержит другую. Это может скрыться, пока Python не покажет это вам!

Если размер вкладки равен ширине пробелов на каждом уровне отступа, то может показаться, что все строки находятся на одном уровне. Однако, если одна строка имеет отступ с использованием пробелов, а другая — с помощью табуляции, Python укажет на это как на проблему:

Здесь строка 5 имеет отступ вместо 4 пробелов. Этот блок кода может выглядеть идеально для вас, или он может выглядеть совершенно неправильно, в зависимости от настроек вашей системы.

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

Обратите внимание на разницу в отображении между тремя примерами выше. Большая часть кода использует 4 пробела для каждого уровня отступа, но строка 5 использует одну вкладку во всех трех примерах. Ширина вкладки изменяется в зависимости от настройки tab width :

Если ширина вкладки равна 4 , то оператор + print + будет выглядеть так, как будто он находится вне цикла + for + . Консоль выведет + ‘done’ + в конце цикла.

Если ширина табуляции равна 8 , что является стандартным для многих систем, то оператор + print + будет выглядеть так, как будто он находится внутри цикла + for + . Консоль будет печатать + ‘done’ + после каждого числа.

Если ширина табуляции равна 3 , то оператор + print + выглядит неуместно. В этом случае строка 5 не соответствует ни одному уровню отступа.

Когда вы запустите код, вы получите следующую ошибку и трассировку:

Обратите внимание на + TabError + вместо обычного + SyntaxError + . Python указывает на проблемную строку и дает вам полезное сообщение об ошибке. Это ясно говорит о том, что в одном и том же файле для отступа используется смесь вкладок и пробелов.

Решение этой проблемы состоит в том, чтобы все строки в одном и том же файле кода Python использовали либо табуляции, либо пробелы, но не обе. Для приведенных выше блоков кода исправление будет состоять в том, чтобы удалить вкладку и заменить ее на 4 пробела, которые будут печатать + ‘done’ + после завершения цикла + for + .

Определение и вызов функций

Вы можете столкнуться с неверным синтаксисом в Python, когда вы определяете или вызываете функции. Например, вы увидите + SyntaxError + , если будете использовать точку с запятой вместо двоеточия в конце определения функции:

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

Кроме того, ключевые аргументы как в определениях функций, так и в вызовах функций должны быть в правильном порядке. Аргументы ключевых слов always идут после позиционных аргументов. Отказ от использования этого порядка приведет к + SyntaxError + :

Здесь, еще раз, сообщение об ошибке очень полезно, чтобы рассказать вам точно, что не так со строкой.

Изменение версий Python

Иногда код, который прекрасно работает в одной версии Python, ломается в более новой версии. Это связано с официальными изменениями в синтаксисе языка. Наиболее известным примером этого является оператор + print + , который перешел от ключевого слова в Python 2 к встроенной функции в Python 3:

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

Другая проблема, с которой вы можете столкнуться, — это когда вы читаете или изучаете синтаксис, который является допустимым синтаксисом в более новой версии Python, но недопустим в той версии, в которую вы пишете. Примером этого является синтаксис f-string, которого нет в версиях Python до 3.6:

В версиях Python до 3.6 интерпретатор ничего не знает о синтаксисе f-строки и просто предоставляет общее сообщение «» неверный синтаксис «`. Проблема, в данном случае, в том, что код looks прекрасно работает, но он был запущен с более старой версией Python. В случае сомнений перепроверьте, какая версия Python у вас установлена!

Синтаксис Python продолжает развиваться, и в Python 3.8 появилось несколько интересных новых функций:

Если вы хотите опробовать некоторые из этих новых функций, то вам нужно убедиться, что вы работаете в среде Python 3.8. В противном случае вы получите + SyntaxError + .

Python 3.8 также предоставляет новый* + SyntaxWarning + *. Вы увидите это предупреждение в ситуациях, когда синтаксис допустим, но все еще выглядит подозрительно. Примером этого может быть отсутствие запятой между двумя кортежами в списке. Это будет действительный синтаксис в версиях Python до 3.8, но код вызовет + TypeError + , потому что кортеж не может быть вызван:

Этот + TypeError + означает, что вы не можете вызывать кортеж, подобный функции, что, как думает интерпретатор Python, вы делаете.

В Python 3.8 этот код все еще вызывает + TypeError + , но теперь вы также увидите + SyntaxWarning + , который указывает, как вы можете решить проблему:

Полезное сообщение, сопровождающее новый + SyntaxWarning + , даже дает подсказку ( » возможно, вы пропустили запятую? » ), Чтобы указать вам правильное направление!

Заключение

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

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

Получение + SyntaxError + во время изучения Python может быть неприятным, но теперь вы знаете, как понимать сообщения трассировки и с какими формами недопустимого синтаксиса в Python вы можете столкнуться. В следующий раз, когда вы получите + SyntaxError + , у вас будет больше возможностей быстро решить проблему!

Solving “inconsistent use of tabs and spaces in indentation” in Visual Studio Code

Out of the blue, when coding Python in Visual Studio Code, you might run into the following error.

“inconsistent use of tabs and spaces in indentation”

This happens, because somewhere in your code, indentation is different than in the rest of your code. Generally, Python doesn’t care what kind of indentation your editor uses, whether it be some spaces, or tabs. But it expects you to be consistent.

Generally, VS Code is pretty good at guessing the kind of indentation is used in the file you’re working in. If you press control + , and scroll down to this setting, you can choose if you want VS Code to detect the kind of indentation in a particular file.

Furthermore, you can get to that same preference and also choose what kind of indentation you want by clicking on the ‘Tab Size: X’ in the bottom right corner of your IDE.

Finally, if you run into the error, and you want to get rid of the spaces (or vice versa), you can paste your code in Notepad++, and do a search and replace by pressing control + H. In the following screenshot I search for 4 spaces and I replace with a tab by entering \t.

How to Write Beautiful Python Code With PEP 8

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Writing Beautiful Pythonic Code With PEP 8

PEP 8, sometimes spelled PEP8 or PEP-8, is a document that provides guidelines and best practices on how to write Python code. It was written in 2001 by Guido van Rossum, Barry Warsaw, and Nick Coghlan. The primary focus of PEP 8 is to improve the readability and consistency of Python code.

PEP stands for Python Enhancement Proposal, and there are several of them. A PEP is a document that describes new features proposed for Python and documents aspects of Python, like design and style, for the community.

This tutorial outlines the key guidelines laid out in PEP 8. It’s aimed at beginner to intermediate programmers, and as such I have not covered some of the most advanced topics. You can learn about these by reading the full PEP 8 documentation.

By the end of this tutorial, you’ll be able to:

  • Write Python code that conforms to PEP 8
  • Understand the reasoning behind the guidelines laid out in PEP 8
  • Set up your development environment so that you can start writing PEP 8 compliant Python code

Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level.

Why We Need PEP 8

PEP 8 exists to improve the readability of Python code. But why is readability so important? Why is writing readable code one of the guiding principles of the Python language?

As Guido van Rossum said, “Code is read much more often than it is written.” You may spend a few minutes, or a whole day, writing a piece of code to process user authentication. Once you’ve written it, you’re never going to write it again. But you’ll definitely have to read it again. That piece of code might remain part of a project you’re working on. Every time you go back to that file, you’ll have to remember what that code does and why you wrote it, so readability matters.

If you’re new to Python, it can be difficult to remember what a piece of code does a few days, or weeks, after you wrote it. If you follow PEP 8, you can be sure that you’ve named your variables well. You’ll know that you’ve added enough whitespace so it’s easier to follow logical steps in your code. You’ll also have commented your code well. All this will mean your code is more readable and easier to come back to. As a beginner, following the rules of PEP 8 can make learning Python a much more pleasant task.

Following PEP 8 is particularly important if you’re looking for a development job. Writing clear, readable code shows professionalism. It’ll tell an employer that you understand how to structure your code well.

If you have more experience writing Python code, then you may need to collaborate with others. Writing readable code here is crucial. Other people, who may have never met you or seen your coding style before, will have to read and understand your code. Having guidelines that you follow and recognize will make it easier for others to read your code.

Naming Conventions

When you write Python code, you have to name a lot of things: variables, functions, classes, packages, and so on. Choosing sensible names will save you time and energy later. You’ll be able to figure out, from the name, what a certain variable, function, or class represents. You’ll also avoid using inappropriate names that might result in errors that are difficult to debug.

Note: Never use l , O , or I single letter names as these can be mistaken for 1 and 0 , depending on typeface:

Naming Styles

The table below outlines some of the common naming styles in Python code and when you should use them:

Type Naming Convention Examples
Function Use a lowercase word or words. Separate words by underscores to improve readability. function , my_function
Variable Use a lowercase single letter, word, or words. Separate words with underscores to improve readability. x , var , my_variable
Class Start each word with a capital letter. Do not separate words with underscores. This style is called camel case or pascal case. Model , MyClass
Method Use a lowercase word or words. Separate words with underscores to improve readability. class_method , method
Constant Use an uppercase single letter, word, or words. Separate words with underscores to improve readability. CONSTANT , MY_CONSTANT , MY_LONG_CONSTANT
Module Use a short, lowercase word or words. Separate words with underscores to improve readability. module.py , my_module.py
Package Use a short, lowercase word or words. Do not separate words with underscores. package , mypackage

These are some of the common naming conventions and examples of how to use them. But in order to write readable code, you still have to be careful with your choice of letters and words. In addition to choosing the correct naming styles in your code, you also have to choose the names carefully. Below are a few pointers on how to do this as effectively as possible.

How to Choose Names

Choosing names for your variables, functions, classes, and so forth can be challenging. You should put a fair amount of thought into your naming choices when writing code as it will make your code more readable. The best way to name your objects in Python is to use descriptive names to make it clear what the object represents.

When naming variables, you may be tempted to choose simple, single-letter lowercase names, like x . But, unless you’re using x as the argument of a mathematical function, it’s not clear what x represents. Imagine you are storing a person’s name as a string, and you want to use string slicing to format their name differently. You could end up with something like this:

This will work, but you’ll have to keep track of what x , y , and z represent. It may also be confusing for collaborators. A much clearer choice of names would be something like this:

Similarly, to reduce the amount of typing you do, it can be tempting to use abbreviations when choosing names. In the example below, I have defined a function db() that takes a single argument x and doubles it:

At first glance, this could seem like a sensible choice. db() could easily be an abbreviation for double. But imagine coming back to this code in a few days. You may have forgotten what you were trying to achieve with this function, and that would make guessing how you abbreviated it difficult.

The following example is much clearer. If you come back to this code a couple of days after writing it, you’ll still be able to read and understand the purpose of this function:

The same philosophy applies to all other data types and objects in Python. Always try to use the most concise but descriptive names possible.

Code Layout

How you lay out your code has a huge role in how readable it is. In this section, you’ll learn how to add vertical whitespace to improve the readability of your code. You’ll also learn how to handle the 79 character line limit recommended in PEP 8.

Blank Lines

Vertical whitespace, or blank lines, can greatly improve the readability of your code. Code that’s bunched up together can be overwhelming and hard to read. Similarly, too many blank lines in your code makes it look very sparse, and the reader might need to scroll more than necessary. Below are three key guidelines on how to use vertical whitespace.

Surround top-level functions and classes with two blank lines. Top-level functions and classes should be fairly self-contained and handle separate functionality. It makes sense to put extra vertical space around them, so that it’s clear they are separate:

Surround method definitions inside classes with a single blank line. Inside a class, functions are all related to one another. It’s good practice to leave only a single line between them:

Use blank lines sparingly inside functions to show clear steps. Sometimes, a complicated function has to complete several steps before the return statement. To help the reader understand the logic inside the function, it can be helpful to leave a blank line between each step.

In the example below, there is a function to calculate the variance of a list. This is two-step problem, so I have indicated each step by leaving a blank line between them. There is also a blank line before the return statement. This helps the reader clearly see what’s returned:

If you use vertical whitespace carefully, it can greatly improved the readability of your code. It helps the reader visually understand how your code splits up into sections, and how those sections relate to one another.

Maximum Line Length and Line Breaking

PEP 8 suggests lines should be limited to 79 characters. This is because it allows you to have multiple files open next to one another, while also avoiding line wrapping.

Of course, keeping statements to 79 characters or less is not always possible. PEP 8 outlines ways to allow statements to run over several lines.

Python will assume line continuation if code is contained within parentheses, brackets, or braces:

If it is impossible to use implied continuation, then you can use backslashes to break lines instead:

However, if you can use implied continuation, then you should do so.

If line breaking needs to occur around binary operators, like + and * , it should occur before the operator. This rule stems from mathematics. Mathematicians agree that breaking before binary operators improves readability. Compare the following two examples.

Below is an example of breaking before a binary operator:

You can immediately see which variable is being added or subtracted, as the operator is right next to the variable being operated on.

Now, let’s see an example of breaking after a binary operator:

Here, it’s harder to see which variable is being added and which is subtracted.

Breaking before binary operators produces more readable code, so PEP 8 encourages it. Code that consistently breaks after a binary operator is still PEP 8 compliant. However, you’re encouraged to break before a binary operator.

Indentation

“There should be one—and preferably only one—obvious way to do it.”

The Zen of Python

Indentation, or leading whitespace, is extremely important in Python. The indentation level of lines of code in Python determines how statements are grouped together.

Consider the following example:

The indented print statement lets Python know that it should only be executed if the if statement returns True . The same indentation applies to tell Python what code to execute when a function is called or what code belongs to a given class.

The key indentation rules laid out by PEP 8 are the following:

  • Use 4 consecutive spaces to indicate indentation.
  • Prefer spaces over tabs.

Tabs vs. Spaces

As mentioned above, you should use spaces instead of tabs when indenting code. You can adjust the settings in your text editor to output 4 spaces instead of a tab character, when you press the Tab key.

If you’re using Python 2 and have used a mixture of tabs and spaces to indent your code, you won’t see errors when trying to run it. To help you to check consistency, you can add a -t flag when running Python 2 code from the command line. The interpreter will issue warnings when you are inconsistent with your use of tabs and spaces:

If, instead, you use the -tt flag, the interpreter will issue errors instead of warnings, and your code will not run. The benefit of using this method is that the interpreter tells you where the inconsistencies are:

Python 3 does not allow mixing of tabs and spaces. Therefore, if you are using Python 3, then these errors are issued automatically:

You can write Python code with either tabs or spaces indicating indentation. But, if you’re using Python 3, you must be consistent with your choice. Otherwise, your code will not run. PEP 8 recommends that you always use 4 consecutive spaces to indicate indentation.

Indentation Following Line Breaks

When you’re using line continuations to keep lines to under 79 characters, it is useful to use indentation to improve readability. It allows the reader to distinguish between two lines of code and a single line of code that spans two lines. There are two styles of indentation you can use.

The first of these is to align the indented block with the opening delimiter:

Sometimes you can find that only 4 spaces are needed to align with the opening delimiter. This will often occur in if statements that span multiple lines as the if , space, and opening bracket make up 4 characters. In this case, it can be difficult to determine where the nested code block inside the if statement begins:

In this case, PEP 8 provides two alternatives to help improve readability:

Add a comment after the final condition. Due to syntax highlighting in most editors, this will separate the conditions from the nested code:

Add extra indentation on the line continuation:

An alternative style of indentation following a line break is a hanging indent. This is a typographical term meaning that every line but the first in a paragraph or statement is indented. You can use a hanging indent to visually represent a continuation of a line of code. Here’s an example:

Note: When you’re using a hanging indent, there must not be any arguments on the first line. The following example is not PEP 8 compliant:

When using a hanging indent, add extra indentation to distinguish the continued line from code contained inside the function. The following example is difficult to read because the code inside the function is at the same indentation level as the continued lines:

Instead, it’s better to use a double indent on the line continuation. This helps you to distinguish between function arguments and the function body, improving readability:

When you write PEP 8 compliant code, the 79 character line limit forces you to add line breaks in your code. To improve readability, you should indent a continued line to show that it is a continued line. There are two ways of doing this. The first is to align the indented block with the opening delimiter. The second is to use a hanging indent. You are free to chose which method of indentation you use following a line break.

Where to Put the Closing Brace

Line continuations allow you to break lines inside parentheses, brackets, or braces. It’s easy to forget about the closing brace, but it’s important to put it somewhere sensible. Otherwise, it can confuse the reader. PEP 8 provides two options for the position of the closing brace in implied line continuations:

Line up the closing brace with the first non-whitespace character of the previous line:

Line up the closing brace with the first character of the line that starts the construct:

You are free to chose which option you use. But, as always, consistency is key, so try to stick to one of the above methods.

Comments

“If the implementation is hard to explain, it’s a bad idea.”

The Zen of Python

You should use comments to document code as it’s written. It is important to document your code so that you, and any collaborators, can understand it. When you or someone else reads a comment, they should be able to easily understand the code the comment applies to and how it fits in with the rest of your code.

Here are some key points to remember when adding comments to your code:

  • Limit the line length of comments and docstrings to 72 characters.
  • Use complete sentences, starting with a capital letter.
  • Make sure to update comments if you change your code.

Block Comments

Use block comments to document a small section of code. They are useful when you have to write several lines of code to perform a single action, such as importing data from a file or updating a database entry. They are important as they help others understand the purpose and functionality of a given code block.

PEP 8 provides the following rules for writing block comments:

  • Indent block comments to the same level as the code they describe.
  • Start each line with a # followed by a single space.
  • Separate paragraphs by a line containing a single # .

Here is a block comment explaining the function of a for loop. Note that the sentence wraps to a new line to preserve the 79 character line limit:

Sometimes, if the code is very technical, then it is necessary to use more than one paragraph in a block comment:

If you’re ever in doubt as to what comment type is suitable, then block comments are often the way to go. Use them as much as possible throughout your code, but make sure to update them if you make changes to your code!

Inline Comments

Inline comments explain a single statement in a piece of code. They are useful to remind you, or explain to others, why a certain line of code is necessary. Here’s what PEP 8 has to say about them:

  • Use inline comments sparingly.
  • Write inline comments on the same line as the statement they refer to.
  • Separate inline comments by two or more spaces from the statement.
  • Start inline comments with a # and a single space, like block comments.
  • Don’t use them to explain the obvious.

Below is an example of an inline comment:

Sometimes, inline comments can seem necessary, but you can use better naming conventions instead. Here’s an example:

Here, the inline comment does give extra information. However using x as a variable name for a person’s name is bad practice. There’s no need for the inline comment if you rename your variable:

Finally, inline comments such as these are bad practice as they state the obvious and clutter code:

Inline comments are more specific than block comments, and it’s easy to add them when they’re not necessary, which leads to clutter. You could get away with only using block comments so, unless you are sure you need an inline comment, your code is more likely to be PEP 8 compliant if you stick to block comments.

Documentation Strings

Documentation strings, or docstrings, are strings enclosed in double ( «»» ) or single ( »’ ) quotation marks that appear on the first line of any function, class, method, or module. You can use them to explain and document a specific block of code. There is an entire PEP, PEP 257, that covers docstrings, but you’ll get a summary in this section.

The most important rules applying to docstrings are the following:

Surround docstrings with three double quotes on either side, as in «»»This is a docstring»»» .

Write them for all public modules, functions, classes, and methods.

Put the «»» that ends a multiline docstring on a line by itself:

For one-line docstrings, keep the «»» on the same line:

For a more detailed article on documenting Python code, see Documenting Python Code: A Complete Guide by James Mertz.

Whitespace in Expressions and Statements

Whitespace can be very helpful in expressions and statements when used properly. If there is not enough whitespace, then code can be difficult to read, as it’s all bunched together. If there’s too much whitespace, then it can be difficult to visually combine related terms in a statement.

Whitespace Around Binary Operators

Surround the following binary operators with a single space on either side:

Comparisons ( == , != , > , < . >= , <= ) and ( is , is not , in , not in )

Note: When = is used to assign a default value to a function argument, do not surround it with spaces.

When there’s more than one operator in a statement, adding a single space before and after each operator can look confusing. Instead, it is better to only add whitespace around the operators with the lowest priority, especially when performing mathematical manipulation. Here are a couple examples:

You can also apply this to if statements where there are multiple conditions:

In the above example, the and operator has lowest priority. It may therefore be clearer to express the if statement as below:

You are free to choose which is clearer, with the caveat that you must use the same amount of whitespace either side of the operator.

The following is not acceptable:

In slices, colons act as a binary operators. Therefore, the rules outlined in the previous section apply, and there should be the same amount of whitespace either side. The following examples of list slices are valid:

In summary, you should surround most operators with whitespace. However, there are some caveats to this rule, such as in function arguments or when you’re combining multiple operators in one statement.

When to Avoid Adding Whitespace

In some cases, adding whitespace can make code harder to read. Too much whitespace can make code overly sparse and difficult to follow. PEP 8 outlines very clear examples where whitespace is inappropriate.

The most important place to avoid adding whitespace is at the end of a line. This is known as trailing whitespace. It is invisible and can produce errors that are difficult to trace.

The following list outlines some cases where you should avoid adding whitespace:

Immediately inside parentheses, brackets, or braces:

Before a comma, semicolon, or colon:

Before the open parenthesis that starts the argument list of a function call:

Before the open bracket that starts an index or slice:

Between a trailing comma and a closing parenthesis:

To align assignment operators:

Make sure that there is no trailing whitespace anywhere in your code. There are other cases where PEP 8 discourages adding extra whitespace, such as immediately inside brackets, as well as before commas and colons. You should also never add extra whitespace in order to align operators.

Programming Recommendations

You will often find that there are several ways to perform a similar action in Python (and any other programming language for that matter). In this section, you’ll see some of the suggestions PEP 8 provides to remove that ambiguity and preserve consistency.

Don’t compare Boolean values to True or False using the equivalence operator. You’ll often need to check if a Boolean value is True or False. When doing so, it is intuitive to do this with a statement like the one below:

The use of the equivalence operator, == , is unnecessary here. bool can only take values True or False . It is enough to write the following:

This way of performing an if statement with a Boolean requires less code and is simpler, so PEP 8 encourages it.

Use the fact that empty sequences are falsy in if statements. If you want to check whether a list is empty, you might be tempted to check the length of the list. If the list is empty, it’s length is 0 which is equivalent to False when used in an if statement. Here’s an example:

However, in Python any empty list, string, or tuple is falsy. We can therefore come up with a simpler alternative to the above:

While both examples will print out List is empty! , the second option is simpler, so PEP 8 encourages it.

Use is not rather than not . is in if statements. If you are trying to check whether a variable has a defined value, there are two options. The first is to evaluate an if statement with x is not None , as in the example below:

A second option would be to evaluate x is None and then have an if statement based on not the outcome:

While both options will be evaluated correctly, the first is simpler, so PEP 8 encourages it.

Don’t use if x: when you mean if x is not None: . Sometimes, you may have a function with arguments that are None by default. A common mistake when checking if such an argument, arg , has been given a different value is to use the following:

This code checks that arg is truthy. Instead, you want to check that arg is not None , so it would be better to use the following:

The mistake being made here is assuming that not None and truthy are equivalent. You could have set arg = [] . As we saw above, empty lists are evaluated as falsy in Python. So, even though the argument arg has been assigned, the condition is not met, and so the code in the body of the if statement will not be executed.

Use .startswith() and .endswith() instead of slicing. If you were trying to check if a string word was prefixed, or suffixed, with the word cat , it might seem sensible to use list slicing. However, list slicing is prone to error, and you have to hardcode the number of characters in the prefix or suffix. It is also not clear to someone less familiar with Python list slicing what you are trying to achieve:

However, this is not as readable as using .startswith() :

Similarly, the same principle applies when you’re checking for suffixes. The example below outlines how you might check whether a string ends in jpg :

While the outcome is correct, the notation is a bit clunky and hard to read. Instead, you could use .endswith() as in the example below:

As with most of these programming recommendations, the goal is readability and simplicity. In Python, there are many different ways to perform the same action, so guidelines on which methods to chose are helpful.

When to Ignore PEP 8

The short answer to this question is never. If you follow PEP 8 to the letter, you can guarantee that you’ll have clean, professional, and readable code. This will benefit you as well as collaborators and potential employers.

However, some guidelines in PEP 8 are inconvenient in the following instances:

  • If complying with PEP 8 would break compatibility with existing software
  • If code surrounding what you’re working on is inconsistent with PEP 8
  • If code needs to remain compatible with older versions of Python

Tips and Tricks to Help Ensure Your Code Follows PEP 8

There is a lot to remember to make sure your code is PEP 8 compliant. It can be a tall order to remember all these rules when you’re developing code. It’s particularly time consuming to update past projects to be PEP 8 compliant. Luckily, there are tools that can help speed up this process. There are two classes of tools that you can use to enforce PEP 8 compliance: linters and autoformatters.

Linters

Linters are programs that analyze code and flag errors. They provide suggestions on how to fix the error. Linters are particularly useful when installed as extensions to your text editor, as they flag errors and stylistic problems while you write. In this section, you’ll see an outline of how the linters work, with links to the text editor extensions at the end.

The best linters for Python code are the following:

pycodestyle is a tool to check your Python code against some of the style conventions in PEP 8.

Install pycodestyle using pip :

You can run pycodestyle from the terminal using the following command:

flake8 is a tool that combines a debugger, pyflakes , with pycodestyle .

Install flake8 using pip :

Run flake8 from the terminal using the following command:

An example of the output is also shown.

Note: The extra line of output indicates a syntax error.

These are also available as extensions for Atom, Sublime Text, Visual Studio Code, and VIM. You can also find guides on setting up Sublime Text and VIM for Python development, as well as an overview of some popular text editors at Real Python.

Autoformatters

Autoformatters are programs that refactor your code to conform with PEP 8 automatically. Once such program is black , which autoformats code following most of the rules in PEP 8. One big difference is that it limits line length to 88 characters, rather than 79. However, you can overwrite this by adding a command line flag, as you’ll see in an example below.

Install black using pip . It requires Python 3.6+ to run:

It can be run via the command line, as with the linters. Let’s say you start with the following code that isn’t PEP 8 compliant in a file called code.py :

You can then run the following command via the command line:

code.py will be automatically reformatted to look like this:

If you want to alter the line length limit, then you can use the —line-length flag:

Two other autoformatters, autopep8 and yapf , perform actions that are similar to what black does.

Another Real Python tutorial, Python Code Quality: Tools & Best Practices by Alexander van Tol, gives a thorough explanation of how to use these tools.

Conclusion

You now know how to write high-quality, readable Python code by using the guidelines laid out in PEP 8. While the guidelines can seem pedantic, following them can really improve your code, especially when it comes to sharing your code with potential employers or collaborators.

In this tutorial, you learned:

  • What PEP 8 is and why it exists
  • Why you should aim to write PEP 8 compliant code
  • How to write code that is PEP 8 compliant

On top of all this, you also saw how to use linters and autoformatters to check your code against PEP 8 guidelines.

If you want to learn more about PEP 8, then you can read the full documentation, or visit pep8.org, which contains the same information but has been nicely formatted. In these documents, you will find the rest of the PEP 8 guidelines not covered in this tutorial.

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Writing Beautiful Pythonic Code With PEP 8

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Jasmine Finer

Jasmine is a Django developer, based in London.

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

TabError: inconsistent use of tabs and spaces in indentation #10561

I prefer Sypder over a larger IDE to have a lighter tool to try some code.
So I am copy-pasting a lot of code from external source, add something, .
Too often I get the error message «TabError: inconsistent use of tabs and spaces in indentation», likely because some code uses spaces other tabs. Manual fixing this is quite cumbersome.
The function «fix identation» does help here either.

On top of that when I actually give up and replace tabs with spaces, delete the tab, insert spaces, the «tool tips» pop up for no reason . and if I press the wrong button, I also suddenly have some code in there which I did not want.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *