- Значения исключений и ошибок в Python
- Синтаксические ошибки (SyntaxError)
- Недостаточно памяти (OutofMemoryError)
- Ошибка рекурсии (RecursionError)
- Ошибка отступа (IndentationError)
- Исключения
- Ошибка типа (TypeError)
- Ошибка деления на ноль (ZeroDivisionError)
- Встроенные исключения
- Ошибка прерывания с клавиатуры (KeyboardInterrupt)
- Стандартные ошибки (StandardError)
- Арифметические ошибки (ArithmeticError)
- Деление на ноль (ZeroDivisionError)
- Переполнение (OverflowError)
- Ошибка утверждения (AssertionError)
- Ошибка атрибута (AttributeError)
- Ошибка импорта (ModuleNotFoundError)
- Ошибка поиска (LookupError)
- Ошибка ключа
- Ошибка индекса
- Ошибка памяти (MemoryError)
- Ошибка имени (NameError)
- Ошибка выполнения (Runtime Error)
- Ошибка типа (TypeError)
- Ошибка значения (ValueError)
- Пользовательские исключения в Python
- Недостатки обработки исключений в Python
- Выводы!
- Неверный синтаксис в Python: общие причины SyntaxError
- Содержание
- Ошибочный синтаксис в Python
- Исключение SyntaxError и трассировка
- Общие проблемы синтаксиса
- Неправильное использование оператора присваивания (=)
- Ошибочное написание, отсутствие или неправильное использование ключевых слов Python
- Отсутствуют круглые скобки, квадратные скобки и кавычки
- Ошибочный синтаксис словаря
- Использование неправильного отступа
- Определение и вызов функций
- Изменение версий Python
- Заключение
Значения исключений и ошибок в Python
Обработка ошибок увеличивает отказоустойчивость кода, защищая его от потенциальных сбоев, которые могут привести к преждевременному завершению работы.
Прежде чем переходить к обсуждению того, почему обработка исключений так важна, и рассматривать встроенные в Python исключения, важно понять, что есть тонкая грань между понятиями ошибки и исключения.
Ошибку нельзя обработать, а исключения Python обрабатываются при выполнении программы. Ошибка может быть синтаксической, но существует и много видов исключений, которые возникают при выполнении и не останавливают программу сразу же. Ошибка может указывать на критические проблемы, которые приложение и не должно перехватывать, а исключения — состояния, которые стоит попробовать перехватить. Ошибки — вид непроверяемых и невозвратимых ошибок, таких как OutOfMemoryError , которые не стоит пытаться обработать.
Обработка исключений делает код более отказоустойчивым и помогает предотвращать потенциальные проблемы, которые могут привести к преждевременной остановке выполнения. Представьте код, который готов к развертыванию, но все равно прекращает работу из-за исключения. Клиент такой не примет, поэтому стоит заранее обработать конкретные исключения, чтобы избежать неразберихи.
Ошибки могут быть разных видов:
- Синтаксические
- Недостаточно памяти
- Ошибки рекурсии
- Исключения
Разберем их по очереди.
Синтаксические ошибки (SyntaxError)
Синтаксические ошибки часто называют ошибками разбора. Они возникают, когда интерпретатор обнаруживает синтаксическую проблему в коде.
Рассмотрим на примере.
Стрелка вверху указывает на место, где интерпретатор получил ошибку при попытке исполнения. Знак перед стрелкой указывает на причину проблемы. Для устранения таких фундаментальных ошибок Python будет делать большую часть работы за программиста, выводя название файла и номер строки, где была обнаружена ошибка.
Недостаточно памяти (OutofMemoryError)
Ошибки памяти чаще всего связаны с оперативной памятью компьютера и относятся к структуре данных под названием “Куча” ( heap ). Если есть крупные объекты (или) ссылки на подобные, то с большой долей вероятности возникнет ошибка OutofMemory . Она может появиться по нескольким причинам:
- Использование 32-битной архитектуры Python (максимальный объем выделенной памяти невысокий, между 2 и 4 ГБ);
- Загрузка файла большого размера;
- Запуск модели машинного обучения/глубокого обучения и много другое;
Обработать ошибку памяти можно с помощью обработки исключений — резервного исключения. Оно используется, когда у интерпретатора заканчивается память и он должен немедленно остановить текущее исполнение. В редких случаях Python вызывает OutofMemoryError , позволяя скрипту каким-то образом перехватить самого себя, остановить ошибку памяти и восстановиться.
Но поскольку Python использует архитектуру управления памятью из языка C (функция malloc() ), не факт, что все процессы восстановятся — в некоторых случаях MemoryError приведет к остановке. Следовательно, обрабатывать такие ошибки не рекомендуется, и это не считается хорошей практикой.
Ошибка рекурсии (RecursionError)
Эта ошибка связана со стеком и происходит при вызове функций. Как и предполагает название, ошибка рекурсии возникает, когда внутри друг друга исполняется много методов (один из которых — с бесконечной рекурсией), но это ограничено размером стека.
Все локальные переменные и методы размещаются в стеке. Для каждого вызова метода создается стековый кадр (фрейм), внутрь которого помещаются данные переменной или результат вызова метода. Когда исполнение метода завершается, его элемент удаляется.
Чтобы воспроизвести эту ошибку, определим функцию recursion , которая будет рекурсивной — вызывать сама себя в бесконечном цикле. В результате появится ошибка StackOverflow или ошибка рекурсии, потому что стековый кадр будет заполняться данными метода из каждого вызова, но они не будут освобождаться.
Ошибка отступа (IndentationError)
Эта ошибка похожа по духу на синтаксическую и является ее подвидом. Тем не менее она возникает только в случае проблем с отступами.
Исключения
Даже если синтаксис в инструкции или само выражение верны, они все равно могут вызывать ошибки при исполнении. Исключения Python — это ошибки, обнаруживаемые при исполнении, но не являющиеся критическими. Скоро вы узнаете, как справляться с ними в программах Python. Объект исключения создается при вызове исключения Python. Если скрипт не обрабатывает исключение явно, программа будет остановлена принудительно.
Программы обычно не обрабатывают исключения, что приводит к подобным сообщениям об ошибке:
Ошибка типа (TypeError)
Ошибка деления на ноль (ZeroDivisionError)
Есть разные типы исключений в Python и их тип выводится в сообщении: вверху примеры TypeError и ZeroDivisionError . Обе строки в сообщениях об ошибке представляют собой имена встроенных исключений Python.
Оставшаяся часть строки с ошибкой предлагает подробности о причине ошибки на основе ее типа.
Теперь рассмотрим встроенные исключения Python.
Встроенные исключения
Прежде чем переходить к разбору встроенных исключений быстро вспомним 4 основных компонента обработки исключения, как показано на этой схеме.
- Try : он запускает блок кода, в котором ожидается ошибка.
- Except : здесь определяется тип исключения, который ожидается в блоке try (встроенный или созданный).
- Else : если исключений нет, тогда исполняется этот блок (его можно воспринимать как средство для запуска кода в том случае, если ожидается, что часть кода приведет к исключению).
- Finally : вне зависимости от того, будет ли исключение или нет, этот блок кода исполняется всегда.
В следующем разделе руководства больше узнаете об общих типах исключений и научитесь обрабатывать их с помощью инструмента обработки исключения.
Ошибка прерывания с клавиатуры (KeyboardInterrupt)
Исключение KeyboardInterrupt вызывается при попытке остановить программу с помощью сочетания Ctrl + C или Ctrl + Z в командной строке или ядре в Jupyter Notebook. Иногда это происходит неумышленно и подобная обработка поможет избежать подобных ситуаций.
В примере ниже если запустить ячейку и прервать ядро, программа вызовет исключение KeyboardInterrupt . Теперь обработаем исключение KeyboardInterrupt .
Стандартные ошибки (StandardError)
Рассмотрим некоторые базовые ошибки в программировании.
Арифметические ошибки (ArithmeticError)
- Ошибка деления на ноль (Zero Division);
- Ошибка переполнения (OverFlow);
- Ошибка плавающей точки (Floating Point);
Все перечисленные выше исключения относятся к классу Arithmetic и вызываются при ошибках в арифметических операциях.
Деление на ноль (ZeroDivisionError)
Когда делитель (второй аргумент операции деления) или знаменатель равны нулю, тогда результатом будет ошибка деления на ноль.
Переполнение (OverflowError)
Ошибка переполнение вызывается, когда результат операции выходил за пределы диапазона. Она характерна для целых чисел вне диапазона.
Ошибка утверждения (AssertionError)
Когда инструкция утверждения не верна, вызывается ошибка утверждения.
Рассмотрим пример. Предположим, есть две переменные: a и b . Их нужно сравнить. Чтобы проверить, равны ли они, необходимо использовать ключевое слово assert , что приведет к вызову исключения Assertion в том случае, если выражение будет ложным.
Ошибка атрибута (AttributeError)
При попытке сослаться на несуществующий атрибут программа вернет ошибку атрибута. В следующем примере можно увидеть, что у объекта класса Attributes нет атрибута с именем attribute .
Ошибка импорта (ModuleNotFoundError)
Ошибка импорта вызывается при попытке импортировать несуществующий (или неспособный загрузиться) модуль в стандартном пути или даже при допущенной ошибке в имени.
Ошибка поиска (LookupError)
LockupError выступает базовым классом для исключений, которые происходят, когда key или index используются для связывания или последовательность списка/словаря неверна или не существует.
Здесь есть два вида исключений:
- Ошибка индекса ( IndexError );
- Ошибка ключа ( KeyError );
Ошибка ключа
Если ключа, к которому нужно получить доступ, не оказывается в словаре, вызывается исключение KeyError .
Ошибка индекса
Если пытаться получить доступ к индексу (последовательности) списка, которого не существует в этом списке или находится вне его диапазона, будет вызвана ошибка индекса (IndexError: list index out of range python).
Ошибка памяти (MemoryError)
Как уже упоминалось, ошибка памяти вызывается, когда операции не хватает памяти для выполнения.
Ошибка имени (NameError)
Ошибка имени возникает, когда локальное или глобальное имя не находится.
В следующем примере переменная ans не определена. Результатом будет ошибка NameError .
Ошибка выполнения (Runtime Error)
Ошибка «NotImplementedError»
Ошибка выполнения служит базовым классом для ошибки NotImplemented . Абстрактные методы определенного пользователем класса вызывают это исключение, когда производные методы перезаписывают оригинальный.
Ошибка типа (TypeError)
Ошибка типа вызывается при попытке объединить два несовместимых операнда или объекта.
В примере ниже целое число пытаются добавить к строке, что приводит к ошибке типа.
Ошибка значения (ValueError)
Ошибка значения вызывается, когда встроенная операция или функция получают аргумент с корректным типом, но недопустимым значением.
В этом примере встроенная операция float получат аргумент, представляющий собой последовательность символов (значение), что является недопустимым значением для типа: число с плавающей точкой.
Пользовательские исключения в Python
В Python есть много встроенных исключений для использования в программе. Но иногда нужно создавать собственные со своими сообщениями для конкретных целей.
Это можно сделать, создав новый класс, который будет наследовать из класса Exception в Python.
В предыдущем примере если ввести что-либо меньше 1, будет вызвано исключение. Многие стандартные исключения имеют собственные исключения, которые вызываются при возникновении проблем в работе их функций.
Недостатки обработки исключений в Python
У использования исключений есть свои побочные эффекты, как, например, то, что программы с блоками try-except работают медленнее, а количество кода возрастает.
Дальше пример, где модуль Python timeit используется для проверки времени исполнения 2 разных инструкций. В stmt1 для обработки ZeroDivisionError используется try-except, а в stmt2 — if . Затем они выполняются 10000 раз с переменной a=0 . Суть в том, чтобы показать разницу во времени исполнения инструкций. Так, stmt1 с обработкой исключений занимает больше времени чем stmt2 , который просто проверяет значение и не делает ничего, если условие не выполнено.
Поэтому стоит ограничить использование обработки исключений в Python и применять его в редких случаях. Например, когда вы не уверены, что будет вводом: целое или число с плавающей точкой, или не уверены, существует ли файл, который нужно открыть.
Выводы!
Как вы могли увидеть, обработка исключений помогает прервать типичный поток программы с помощью специального механизма, который делает код более отказоустойчивым.
Обработка исключений — один из основных факторов, который делает код готовым к развертыванию. Это простая концепция, построенная всего на 4 блоках: try выискивает исключения, а except их обрабатывает.
Очень важно поупражняться в их использовании, чтобы сделать свой код более отказоустойчивым.
Источник
Неверный синтаксис в Python: общие причины SyntaxError
Python известен своим простым синтаксисом. Однако, когда вы изучаете Python впервые или когда вы пришли к Python, имея солидный опыт работы с другим языком программирования, вы можете столкнуться с некоторыми вещами, которые Python не допускает. Если вы когда-либо получали ошибку SyntaxError при попытке запустить код Python. Здесь вы увидите распространенные примеры недопустимого синтаксиса в Python и узнаете, как решать эти проблемы.
К концу урока вы сможете:
- Определить недопустимый синтаксис в Python.
- Разберитесь с трассировкой SyntaxError.
- Устранить недопустимый синтаксис или вообще предотвратить его.
Содержание
Ошибочный синтаксис в Python
Когда вы запускаете свой код Python, интерпретатор сначала анализирует его, чтобы преобразовать в байт-код Python, который затем выполняет. Интерпретатор обнаружит любой недопустимый синтаксис в Python на этом первом этапе выполнения программы, также известном как этап синтаксического анализа. Если интерпретатор не может успешно проанализировать ваш код Python, то это означает, что где-то в коде вы использовали неверный синтаксис. Интерпретатор попытается показать вам, где произошла эта ошибка.
Когда вы впервые изучаете Python, может быть неприятно получить SyntaxError. Python попытается помочь вам определить неправильный синтаксис в вашем коде, но трассировка, которую он предоставляет, может немного сбивать с толку. Иногда код, на который он указывает, совершенно нормален.
Примечание. Если ваш код синтаксически правильный, вы можете получить другие исключения, которые не являются SyntaxError. Чтобы узнать больше о других исключениях Python и о том, как с ними обращаться, ознакомьтесь со статьей «Исключения Python: Введение».
Вы не можете обрабатывать недопустимый синтаксис в Python, как и другие исключения. Даже если вы попытаетесь обернуть try . except обойти код с недопустимым синтаксисом, вы все равно увидите, что интерпретатор вызывает ошибку SyntaxError.
Исключение SyntaxError и трассировка
Когда интерпретатор обнаруживает недопустимый синтаксис в коде Python, он вызывает исключение SyntaxError и предоставляет обратную трассировку с некоторой полезной информацией, которая поможет вам отладить ошибку. Вот код, который содержит недопустимый синтаксис в Python:
Вы можете увидеть недопустимый синтаксис в словарном литерале в строке 4. Во второй записи, ‘jim’ , отсутствует запятая. Если вы попытаетесь запустить этот код как есть, то получите следующую трассировку:
Обратите внимание, что сообщение трассировки обнаруживает ошибку в строке 5, а не в строке 4. Интерпретатор Python пытается указать, где находится недопустимый синтаксис. Однако на самом деле он может указывать только на то, где впервые заметил проблему. Когда вы получаете трассировку SyntaxError и код, на который указывает трассировка, выглядит нормально,тогда вы захотите начать движение назад по коду, пока не сможете определить, что не так.
В приведенном выше примере нет проблем с пропуском запятой, в зависимости от того, что идет после нее. Например, нет проблем с пропущенной запятой после слова michael в строке 5. Но как только интерпретатор сталкивается с чем-то, что не имеет смысла, он может указать вам только на первое, что он обнаружит, чего он не может понять.
Примечание. В этом руководстве предполагается, что вы знакомы с основами трассировки Python. Чтобы узнать больше о трассировке Python и о том, как ее читать, ознакомьтесь с разделами «Понимание трассировки Python» и «Получение максимальной отдачи от трассировки Python».
Есть несколько элементов трассировки SyntaxError, которые могут помочь вам определить, где в вашем коде находится недопустимый синтаксис:
- Имя файла, в котором обнаружен недопустимый синтаксис.
- Номер строки и воспроизведенная строка кода, в которой возникла проблема.
- Каретка (^) в строке под воспроизводимым кодом, который показывает вам ту точку кода, в которой есть проблема.
- Сообщение об ошибке, которое появляется после типа исключения SyntaxError, которое может предоставить информацию, которая поможет вам определить проблему.
В приведенном выше примере имя файла было theofficefacts.py, номер строки был 5, а курсор указывал на закрывающую кавычку словарного ключа michael. Трассировка SyntaxError может не указывать на настоящую проблему, но она укажет на первое место, где интерпретатор не может понять синтаксис.
Есть два других исключения, которые могут вызвать Python. Они эквивалентны SyntaxError, но имеют разные имена:
Оба эти исключения наследуются от класса SyntaxError, но это особые случаи, когда речь идет об отступах. Ошибка IndentationError возникает, когда уровни отступа вашего кода не совпадают. Ошибка TabError возникает, когда в вашем коде используются как табуляции, так и пробелы в одном файле. Вы подробнее рассмотрите эти исключения в следующем разделе.
Общие проблемы синтаксиса
Когда вы впервые сталкиваетесь с SyntaxError, полезно знать, почему возникла проблема и что вы можете сделать, чтобы исправить недопустимый синтаксис в вашем коде Python. В разделах ниже вы увидите некоторые из наиболее распространенных причин, по которым может возникать SyntaxError, и способы их устранения.
Неправильное использование оператора присваивания (=)
В Python есть несколько случаев, когда вы не можете назначать объекты. Некоторые примеры присваиваются литералам и вызовам функций. В блоке кода ниже вы можете увидеть несколько примеров, которые пытаются это сделать, и результирующие трассировки SyntaxError:
Первый пример пытается присвоить значение 5 вызову len() . В этом случае очень полезно сообщение SyntaxError. Он сообщает вам, что вы не можете присвоить значение вызову функции.
Второй и третий примеры пытаются присвоить литералам строку и целое число. То же правило верно и для других буквальных значений. Снова,сообщения трассировки указывают, что проблема возникает при попытке присвоить значение литералу.
Примечание. В приведенных выше примерах отсутствует повторяющаяся строка кода и курсор (^), указывающий на проблему в трассировке. Исключение и трассировка, которые вы видите, будут другими, когда вы находитесь в REPL и пытаетесь выполнить этот код из файла. Если бы этот код был в файле, вы бы получили повторяющуюся строку кода и курсор, указывающий на проблему, как вы видели в других случаях в этом уроке.
Скорее всего, вы не собираетесь присвоить значение литералу или вызову функции. Например, это может произойти, если вы случайно оставите лишний знак равенства (=), который превратит присвоение в сравнение. Сравнение, как вы можете видеть ниже, было бы справедливым:
В большинстве случаев, когда Python сообщает вам, что вы назначаете что-то, что не может быть назначено, вы сначала можете проверить, чтобы убедиться, что оператор не должен быть логическим выражением. Вы также можете столкнуться с этой проблемой, когда пытаетесь присвоить значение ключевому слову Python, о чем вы узнаете в следующем разделе.
Ошибочное написание, отсутствие или неправильное использование ключевых слов Python
Ключевые слова Python — это набор защищенных слов, которые имеют особое значение в Python. Это слова, которые нельзя использовать в качестве идентификаторов, переменных или имен функций в коде. Они являются частью языка и могут использоваться только в том контексте, который позволяет Python.
Есть три распространенных способа ошибочного использования ключевых слов:
- Неправильное написание ключевого слова.
- Отсутствует ключевое слово.
- Неправильное использование ключевого слова.
Если вы неправильно написали ключевое слово в коде Python, вы получите ошибку SyntaxError. Например, вот что произойдет, если вы неправильно напишете ключевое слово для:
В сообщении написано SyntaxError: недопустимый синтаксис, но это не очень помогает. Отслеживание указывает на первое место, где Python мог обнаружить, что что-то не так. Чтобы исправить эту ошибку, убедитесь, что все ключевые слова Python написаны правильно.
Еще одна распространенная проблема с ключевыми словами — это когда вы их вообще пропускаете:
Еще раз, сообщение об исключении не так уж и полезно, но трассировка действительно пытается указать вам в правильном направлении. Если вы отойдете от каретки, то увидите, что ключевое слово in отсутствует в синтаксисе цикла for .
Вы также можете неправильно использовать защищенное ключевое слово Python. Помните, что ключевые слова разрешено использовать только в определенных ситуациях. Если вы используете их неправильно, в вашем коде Python будет недопустимый синтаксис. Типичный пример этого — использование continue или break вне цикла. Это легко может произойти во время разработки, когда вы что-то реализуете и случайно перемещаете логику за пределы цикла:
Здесь Python отлично сообщает вам, что именно не так. Сообщения ‘break’ outside loop и ‘continue’ not properly in loop помогают точно понять, что делать. Если бы этот код находился в файле, то у Python также была бы каретка, указывающая прямо на неправильно использованное ключевое слово. Другой пример: вы пытаетесь назначить ключевое слово Python переменной или использовать ключевое слово для определения функции:
Когда вы пытаетесь назначить значение для передачи или когда вы пытаетесь определить новую функцию с именем pass, вы получите SyntaxError и снова увидите сообщение invalid syntax.
Исправить этот тип недопустимого синтаксиса в коде 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.iskeyword(). Если вам просто нужен быстрый способ проверить передаваемую переменную, вы можете использовать следующий однострочник:
Этот код быстро скажет вам, является ли идентификатор, который вы пытаетесь использовать, ключевым словом или нет.
Отсутствуют круглые скобки, квадратные скобки и кавычки
Часто причиной неправильного синтаксиса в коде Python является пропущенная или несоответствующая закрывающая круглая или квадратная скобка, или цитата. Их может быть трудно обнаружить в очень длинных строках вложенных скобок или в более длинных многострочных блоках. Вы можете обнаружить несоответствующие или отсутствующие кавычки с помощью трассировки Python:
Здесь трассировка указывает на недопустимый код, где после закрывающей одинарной кавычки стоит t’ . Чтобы исправить это, вы можете внести одно из двух изменений:
- Экранируйте одинарную кавычку с помощью обратной косой черты ( ‘don\’t’ ).
- Вместо этого заключите всю строку в двойные кавычки ( «don’t» ).
Еще одна распространенная ошибка — забыть закрыть строку. Как с двойными кавычками, так и с одинарными строками в кавычках, ситуация и трассировка одинаковы:
На этот раз курсор в трассировке указывает прямо на код проблемы. Сообщение SyntaxError EOL while scanning string literal является немного более конкретным и полезным для определения проблемы. Это означает, что интерпретатор Python дошел до конца строки (EOL) до того, как открытая строка была закрыта. Чтобы исправить это, закройте строку кавычкой, которая соответствует той, которую вы использовали для ее начала. В этом случае это будет двойная кавычка ( » ).
Кавычки, отсутствующие в операторах внутри f‑строки, также могут привести к неверному синтаксису в Python:
Здесь в ссылке на словарь возрастов внутри напечатанной f‑строки отсутствует закрывающая двойная кавычка из ключевой ссылки. Результирующая трассировка выглядит следующим образом:
Python идентифицирует проблему и сообщает вам, что она существует внутри f‑строки. Сообщение f-string: unterminated string также указывает, в чем проблема. Каретка в этом случае указывает только на начало f‑строки.
Это может быть не так полезно, как если бы курсор указывает на проблемную область f‑строки, но это сужает область, где вам нужно искать. Где-то внутри этой f‑строки есть незавершенная фраза. Вам просто нужно узнать где. Чтобы решить эту проблему, убедитесь, что присутствуют все внутренние кавычки и скобки f‑строки.
То же самое с отсутствием круглых или квадратных скобок. Если вы, например, опустите закрывающую квадратную скобку в списке, Python заметит это и укажет на нее. Однако есть несколько вариантов этого. Первый — убрать закрывающую скобку из списка:
Когда вы запустите этот код, вам сообщат, что возникла проблема с вызовом print() :
Дело в том, что Python считает, что список содержит три элемента: 1 , 2 и 3 print(foo()) . Python использует пробелы для логической группировки элементов и поскольку нет запятой или скобок, отделяющих 3 от print(foo()) , Python объединяет их вместе как третий элемент списка. Другой вариант — добавить запятую после последнего элемента в списке, но при этом оставить закрывающую квадратную скобку:
Теперь у вас другая трассировка:
В предыдущем примере 3 и print(foo()) были объединены как один элемент, но здесь вы видите запятую, разделяющую их. Теперь вызов print(foo()) добавляется как четвертый элемент списка, и Python достигает конца файла без закрывающей скобки. Трассировка сообщает вам, что Python дошел до конца файла (EOF), но он ожидал чего-то другого.
В этом примере Python ожидал закрывающую скобку ( ] ), но повторяющаяся строка и курсор не очень полезны. Python не может определить отсутствие скобок. Иногда единственное, что вы можете сделать, — это начать с курсора и двигаться назад, пока не сможете определить, что отсутствует, а что нет.
Ошибочный синтаксис словаря
Ранее вы видели, что вы можете получить SyntaxError, если оставите запятую в элементе словаря. Другой формой недопустимого синтаксиса со словарями Python является использование знака равенства ( = ) для разделения ключей и значений вместо двоеточия:
Еще раз, это сообщение об ошибке не очень помогает. Однако повторяющаяся линия и курсор очень полезны! Они указывают прямо на проблемного персонажа.
Этот тип проблемы часто встречается, если вы путаете синтаксис Python с синтаксисом других языков программирования. Вы также увидите это, если перепутаете определение словаря с вызовом dict() . Чтобы исправить это, вы можете заменить знак равенства двоеточием. Вы также можете переключиться на использование dict() :
Вы можете использовать dict() для определения словаря, если этот синтаксис более полезен.
Использование неправильного отступа
Есть два подкласса SyntaxError, которые конкретно решают проблемы с отступами:
В то время как другие языки программирования используют фигурные скобки для обозначения блоков кода, Python использует пробелы. Это означает, что Python ожидает, что пробелы в вашем коде будут вести себя предсказуемо. Он вызовет ошибку IndentationError, если в блоке кода есть строка с неправильным количеством пробелов:
Это может быть трудно увидеть, но строка 5 имеет отступ только на 2 пробела. Он должен соответствовать оператору цикла for , который занимает 4 пробела. К счастью, Python может легко обнаружить это и быстро сказать вам, в чем проблема.
Однако здесь есть некоторая двусмысленность. Строка print(‘done’) должна быть после цикла for или внутри блока цикла for ? Когда вы запустите приведенный выше код, вы увидите следующую ошибку:
Хотя трассировка очень похожа на трассировку SyntaxError, на самом деле это ошибка IndentationError. Сообщение об ошибке также очень полезно. Он сообщает вам, что уровень отступа строки не соответствует ни одному уровню отступа. Другими словами, print(‘done’) имеет отступ в 2 пробела, но Python не может найти никакой другой строки кода, соответствующей этому уровню отступа. Это можно быстро исправить, убедившись, что код соответствует ожидаемому уровню отступа.
Другой тип SyntaxError — это TabError, который вы будете видеть всякий раз, когда есть строка, содержащая табуляторы или пробелы для ее отступа,в то время как остальная часть файла содержит другой. Это может быть скрыто, пока Python не укажет вам на это!
Если размер табуляции такой же, как и количество пробелов на каждом уровне отступа, может показаться, что все строки находятся на одном уровне. Однако, если одна строка имеет отступ с использованием пробелов, а другая — с помощью табуляции,тогда Python укажет на это как на проблему:
Здесь строка 5 имеет отступ с табуляции вместо 4 пробелов. Этот блок кода может выглядеть идеально для вас или может выглядеть совершенно неправильно, в зависимости от настроек вашей системы.
Однако Python сразу же заметит проблему. Но прежде чем запустить код, чтобы увидеть, что Python скажет вам об ошибке, возможно, вам будет полезно увидеть пример того, как выглядит код при разных настройках ширины вкладки:
Обратите внимание на разницу в отображении между тремя приведенными выше примерами. Большая часть кода использует 4 пробела для каждого уровня отступа, но в строке 5 во всех трех примерах используется одна табуляция. Ширина вкладки изменяется в зависимости от настройки ширины вкладки:
- Если ширина табуляции равна 4, то оператор печати будет выглядеть так, как будто он находится вне цикла for. Консоль напечатает ‘done’ в конце цикла.
- Если ширина табуляции равна 8, что является стандартом для многих систем, тогда оператор печати будет выглядеть так, как будто он находится внутри цикла for. После каждого числа консоль будет печатать ‘done’ .
- Если ширина табуляции равна 3, то оператор печати выглядит неуместным. В этом случае строка 5 не соответствует ни одному уровню отступа.
Когда вы запустите код, вы получите следующую ошибку и трассировку:
Обратите внимание на TabError вместо обычного SyntaxError. Python указывает на проблемную строку и выдает полезное сообщение об ошибке. Он четко говорит о том, что в одном файле для отступов используется смесь табуляции и пробелов.
Решение состоит в том, чтобы использовать во всех строках одного файла кода Python либо табуляции, либо пробелы, но не то и другое вместе. Для приведенных выше блоков кода исправление будет заключаться в удалении табуляции и замене ее четырьмя пробелами, которые будут печатать ‘done’ после завершения цикла for .
Определение и вызов функций
Вы можете столкнуться с недопустимым синтаксисом в Python при определении или вызове функций. Например, вы увидите SyntaxError, если используете точку с запятой вместо двоеточия в конце определения функции:
Отслеживание здесь очень полезно, поскольку курсор указывает прямо на проблемный символ. Вы можете устранить этот недопустимый синтаксис в Python, заменив точку с запятой двоеточием.
Кроме того, аргументы ключевых слов как в определениях функций, так и в вызовах функций должны быть в правильном порядке. Аргументы ключевого слова всегда идут после позиционных аргументов. Несоблюдение этого порядка приведет к ошибке SyntaxError:
Здесь, опять же, сообщение об ошибке очень помогает, говоря вам, что именно не так с линией.
Изменение версий Python
Иногда код, который отлично работает в одной версии Python, ломается в более новой версии. Это связано с официальными изменениями синтаксиса языка. Наиболее известным примером этого является оператор печати, который превратился из ключевого слова в Python 2 во встроенную функцию в Python 3:
Это один из примеров, когда появляется сообщение об ошибке с SyntaxError! Он не только сообщает вам, что вам не хватает круглых скобок в вызове print , но также предоставляет правильный код, который поможет вам исправить оператор.
Другая проблема, с которой вы можете столкнуться, — это когда вы читаете или изучаете синтаксис, который является допустимым синтаксисом в более новой версии Python, но недействителен в версии, в которой вы пишете. Примером этого является синтаксис f-строки, который не существует в версиях Python до 3.6:
В версиях Python до 3.6 интерпретатор ничего не знает о синтаксисе f-строки и просто выдает общее сообщение invalid syntax. Проблема в этом случае в том, что код выглядит отлично, но он был запущен с более старой версией 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, даже содержит подсказку «perhaps you missed a comma?» («возможно, вы пропустили запятую?»), Чтобы указать вам правильное направление!
Заключение
В этом руководстве вы увидели, какую информацию дает трассировка SyntaxError. Вы также видели много распространенных примеров неверного синтаксиса в Python и способы решения этих проблем. Это не только ускорит ваш рабочий процесс, но и сделает вас более полезным рецензентом кода!
Когда вы пишете код, попробуйте использовать среду IDE એ , которая понимает синтаксис Python и предоставляет обратную связь. Если вы поместите множество примеров недопустимого кода Python из этого руководства в хорошую среду IDE એ , они должны выделить проблемные строки еще до того, как вы сможете выполнить свой код.
Ошибка SyntaxError при изучении Python может быть неприятной,но теперь вы знаете, как понимать сообщения трассировки и с какими формами недопустимого синтаксиса в Python вы можете столкнуться. В следующий раз, когда вы получите SyntaxError, вы будете лучше подготовлены, чтобы быстро исправить проблему!
Источник