Как исправить ошибку в питоне
Программа не работает. Что делать?
Моя программа не работает! Что делать? В данной статье я постараюсь собрать наиболее частые ошибки начинающих программировать на python 3, а также расскажу, как их исправлять.
Проблема: Моя программа не запускается. На доли секунды появляется чёрное окошко, а затем исчезает.
Причина: после окончания выполнения программы (после выполнения всего кода или при возникновении исключения программа закрывается. И если вы её вызвали двойным кликом по иконке (а вы, скорее всего, вызвали её именно так), то она закроется вместе с окошком, в котором находится вывод программы.
Решение: запускать программу через IDLE или через консоль.
Проблема: Не работает функция input. Пишет SyntaxError.
Причина: Вы запустили Python 2.
Проблема: Где-то увидел простую программу, а она не работает.
Причина: Вам подсунули программу на Python 2.
Решение: Прочитать об отличиях Python 2 от Python 3. Переписать её на Python 3. Например, данная программа на Python 3 будет выглядеть так:
Проблема: TypeError: Can’t convert ‘int’ object to str implicitly.
Причина: Нельзя складывать строку с числом.
Решение: Привести строку к числу с помощью функции int(). Кстати, заметьте, что функция input() всегда возвращает строку!
Проблема: SyntaxError: invalid syntax.
Причина: Забыто двоеточие.
Проблема: SyntaxError: invalid syntax.
Причина: Забыто равно.
Проблема: NameError: name ‘a’ is not defined.
Причина: Переменная «a» не существует. Возможно, вы опечатались в названии или забыли инициализировать её.
Решение: Исправить опечатку.
Проблема: IndentationError: expected an indented block.
Причина: Нужен отступ.
Проблема: TabError: inconsistent use of tabs and spaces in indentation.
Причина: Смешение пробелов и табуляции в отступах.
Решение: Исправить отступы.
Проблема: UnboundLocalError: local variable ‘a’ referenced before assignment.
Причина: Попытка обратиться к локальной переменной, которая ещё не создана.
Проблема: Программа выполнилась, но в файл ничего не записалось / записалось не всё.
Причина: Не закрыт файл, часть данных могла остаться в буфере.
Проблема: Здесь может быть ваша проблема. Комментарии чуть ниже 🙂
Значения исключений и ошибок в Python
Обработка ошибок увеличивает отказоустойчивость кода, защищая его от потенциальных сбоев, которые могут привести к преждевременному завершению работы.
Прежде чем переходить к обсуждению того, почему обработка исключений так важна, и рассматривать встроенные в Python исключения, важно понять, что есть тонкая грань между понятиями ошибки и исключения.
Обработка исключений делает код более отказоустойчивым и помогает предотвращать потенциальные проблемы, которые могут привести к преждевременной остановке выполнения. Представьте код, который готов к развертыванию, но все равно прекращает работу из-за исключения. Клиент такой не примет, поэтому стоит заранее обработать конкретные исключения, чтобы избежать неразберихи.
Ошибки могут быть разных видов:
Разберем их по очереди.
Синтаксические ошибки (SyntaxError)
Синтаксические ошибки часто называют ошибками разбора. Они возникают, когда интерпретатор обнаруживает синтаксическую проблему в коде.
Рассмотрим на примере.
Стрелка вверху указывает на место, где интерпретатор получил ошибку при попытке исполнения. Знак перед стрелкой указывает на причину проблемы. Для устранения таких фундаментальных ошибок Python будет делать большую часть работы за программиста, выводя название файла и номер строки, где была обнаружена ошибка.
Недостаточно памяти (OutofMemoryError)
Но поскольку Python использует архитектуру управления памятью из языка C (функция malloc() ), не факт, что все процессы восстановятся — в некоторых случаях MemoryError приведет к остановке. Следовательно, обрабатывать такие ошибки не рекомендуется, и это не считается хорошей практикой.
Ошибка рекурсии (RecursionError)
Эта ошибка связана со стеком и происходит при вызове функций. Как и предполагает название, ошибка рекурсии возникает, когда внутри друг друга исполняется много методов (один из которых — с бесконечной рекурсией), но это ограничено размером стека.
Все локальные переменные и методы размещаются в стеке. Для каждого вызова метода создается стековый кадр (фрейм), внутрь которого помещаются данные переменной или результат вызова метода. Когда исполнение метода завершается, его элемент удаляется.
Ошибка отступа (IndentationError)
Эта ошибка похожа по духу на синтаксическую и является ее подвидом. Тем не менее она возникает только в случае проблем с отступами.
Исключения
Даже если синтаксис в инструкции или само выражение верны, они все равно могут вызывать ошибки при исполнении. Исключения Python — это ошибки, обнаруживаемые при исполнении, но не являющиеся критическими. Скоро вы узнаете, как справляться с ними в программах Python. Объект исключения создается при вызове исключения Python. Если скрипт не обрабатывает исключение явно, программа будет остановлена принудительно.
Программы обычно не обрабатывают исключения, что приводит к подобным сообщениям об ошибке:
Ошибка типа (TypeError)
Ошибка деления на ноль (ZeroDivisionError)
Оставшаяся часть строки с ошибкой предлагает подробности о причине ошибки на основе ее типа.
Теперь рассмотрим встроенные исключения Python.
Встроенные исключения
Прежде чем переходить к разбору встроенных исключений быстро вспомним 4 основных компонента обработки исключения, как показано на этой схеме.
В следующем разделе руководства больше узнаете об общих типах исключений и научитесь обрабатывать их с помощью инструмента обработки исключения.
Ошибка прерывания с клавиатуры (KeyboardInterrupt)
Исключение KeyboardInterrupt вызывается при попытке остановить программу с помощью сочетания Ctrl + C или Ctrl + Z в командной строке или ядре в Jupyter Notebook. Иногда это происходит неумышленно и подобная обработка поможет избежать подобных ситуаций.
Стандартные ошибки (StandardError)
Рассмотрим некоторые базовые ошибки в программировании.
Арифметические ошибки (ArithmeticError)
Все перечисленные выше исключения относятся к классу Arithmetic и вызываются при ошибках в арифметических операциях.
Деление на ноль (ZeroDivisionError)
Когда делитель (второй аргумент операции деления) или знаменатель равны нулю, тогда результатом будет ошибка деления на ноль.
Переполнение (OverflowError)
Ошибка переполнение вызывается, когда результат операции выходил за пределы диапазона. Она характерна для целых чисел вне диапазона.
Ошибка утверждения (AssertionError)
Когда инструкция утверждения не верна, вызывается ошибка утверждения.
Ошибка атрибута (AttributeError)
Ошибка импорта (ModuleNotFoundError)
Ошибка импорта вызывается при попытке импортировать несуществующий (или неспособный загрузиться) модуль в стандартном пути или даже при допущенной ошибке в имени.
Ошибка поиска (LookupError)
LockupError выступает базовым классом для исключений, которые происходят, когда key или index используются для связывания или последовательность списка/словаря неверна или не существует.
Здесь есть два вида исключений:
Ошибка ключа
Ошибка индекса
Если пытаться получить доступ к индексу (последовательности) списка, которого не существует в этом списке или находится вне его диапазона, будет вызвана ошибка индекса (IndexError: list index out of range python).
Ошибка памяти (MemoryError)
Как уже упоминалось, ошибка памяти вызывается, когда операции не хватает памяти для выполнения.
Ошибка имени (NameError)
Ошибка имени возникает, когда локальное или глобальное имя не находится.
Ошибка выполнения (Runtime Error)
Ошибка типа (TypeError)
Ошибка типа вызывается при попытке объединить два несовместимых операнда или объекта.
В примере ниже целое число пытаются добавить к строке, что приводит к ошибке типа.
Ошибка значения (ValueError)
Ошибка значения вызывается, когда встроенная операция или функция получают аргумент с корректным типом, но недопустимым значением.
В этом примере встроенная операция float получат аргумент, представляющий собой последовательность символов (значение), что является недопустимым значением для типа: число с плавающей точкой.
Пользовательские исключения в Python
В Python есть много встроенных исключений для использования в программе. Но иногда нужно создавать собственные со своими сообщениями для конкретных целей.
Это можно сделать, создав новый класс, который будет наследовать из класса Exception в Python.
В предыдущем примере если ввести что-либо меньше 1, будет вызвано исключение. Многие стандартные исключения имеют собственные исключения, которые вызываются при возникновении проблем в работе их функций.
Недостатки обработки исключений в Python
У использования исключений есть свои побочные эффекты, как, например, то, что программы с блоками try-except работают медленнее, а количество кода возрастает.
Поэтому стоит ограничить использование обработки исключений в Python и применять его в редких случаях. Например, когда вы не уверены, что будет вводом: целое или число с плавающей точкой, или не уверены, существует ли файл, который нужно открыть.
Выводы!
Как вы могли увидеть, обработка исключений помогает прервать типичный поток программы с помощью специального механизма, который делает код более отказоустойчивым.
Обработка исключений — один из основных факторов, который делает код готовым к развертыванию. Это простая концепция, построенная всего на 4 блоках: try выискивает исключения, а except их обрабатывает.
Очень важно поупражняться в их использовании, чтобы сделать свой код более отказоустойчивым.
Python Traceback — Как правильно исправлять ошибки в коде
Python выводит трассировку (далее traceback), когда в вашем коде появляется ошибка. Вывод traceback может быть немного пугающим, если вы видите его впервые, или не понимаете, чего от вас хотят. Однако traceback Python содержит много информации, которая может помочь вам определить и исправить причину, из-за которой в вашем коде возникла ошибка.
Содержание статьи
Понимание того, какую информацию предоставляет traceback Python является основополагающим критерием того, как стать лучшим Python программистом.
К концу данной статьи вы сможете:
Python Traceback — Как правильно читать трассировку?
Traceback (трассировка) — это отчет, который содержит вызовы выполненных функций в вашем коде в определенный момент.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Traceback называют по разному, иногда они упоминаются как трассировка стэка, обратная трассировка, и так далее. В Python используется определение “трассировка”.
Когда ваша программа выдает ошибку, Python выводит текущую трассировку, чтобы подсказать вам, что именно пошло не так. Ниже вы увидите пример, демонстрирующий данную ситуацию:
Обратите внимание: в данной статье подразумевается, что вы уже имеете представление об ошибках Python. Если это вам не знакомо, или вы хотите освежить память, можете ознакомиться с нашей статьей: Обработка ошибок в Python
Когда вы запускаете эту программу, вы получите следующую трассировку:
Эта выдача из traceback содержит массу информации, которая вам понадобится для определения проблемы. Последняя строка трассировки говорит нам, какой тип ошибки возник, а также дополнительная релевантная информация об ошибке. Предыдущие строки из traceback указывают на код, из-за которого возникла ошибка.
Python Traceback — Как правильно понять в чем ошибка?
Трассировка Python содержит массу полезной информации, когда вам нужно определить причину ошибки, возникшей в вашем коде. В данном разделе, мы рассмотрим различные виды traceback, чтобы понять ключевые отличия информации, содержащейся в traceback.
Подробный обзор структуры трассировки в Python 3
Существует несколько секций для каждой трассировки Python, которые являются крайне важными. Диаграмма ниже описывает несколько частей:
В Python лучше всего читать трассировку снизу вверх.
Есть ряд отличий между выдачей трассировок, когда вы запускает код в командной строке, и между запуском кода в REPL. Ниже вы можете видеть тот же код из предыдущего раздела, запущенного в REPL и итоговой выдачей трассировки:
Профессиональная обработка ошибок в Python Alex Grigorovich
В этом уроке вы узнаете, как обрабатывать ошибки в Python со всех возможных точек зрения. Обработка ошибок является важнейшим аспектом проектирования, и она проходит от самых низких уровней (иногда это аппаратное обеспечение) через весь путь к конечным пользователям. Если у вас нет продуманной стратегии в этой области, ваша система будет ненадежной, а пользовательский опыт будет плохим, и вы будете иметь много проблем с отладкой и устранением неполадок.
Ключ к успеху, зная обо всех связанных сторонах вопроса, рассматривать их целостно и сформировать решение, которое учитывает каждый аспект.
Коды статуса против Исключений
Существует две основных модели обработок ошибок: Коды статуса и Исключения. Коды статуса могут использоваться в любом языке программирования. Исключения требуют поддержки языка/среды исполнения.
Python поддерживает исключения. Python и его стандартная библиотека использует исключения свободно для того, чтобы сообщить о различных состояниях, таких как IO ошибки, ошибки деления на ноль, ошибки пределов индексации, а также некоторые некритичные ситуаций, такие как конец итерации (хотя обычно эти ошибки скрыты). Большинство библиотек придерживаются этого принципа и вызывают исключения.
Это означает, что ваш код будет обрабатывать исключения, возникающие в Python или в библиотеке, во всяком случае, так что вы можете также вызывать исключения напрямую из вашего кода, когда это необходимо и не полагаться на коды статуса.
Небольшой пример
Прежде чем погрузиться в святая святых лучших практик обработки исключений и ошибок Python, давайте рассмотрим некоторые исключения в действии:
Исключения Python
Python исключениями являются объекты организованные в классовой иерархии.
Вот иерархия целиком:
Когда вы получаете исключение или функция, которую вы выполнили вызывает исключение, обычный порядок кода завершается и исключение начинает распространятся вверх по стеку вызовов до тех пор, пока не встречает обработчик соответствующих исключений. Если обработчик не доступен, процесс (или, точнее, текущий поток) будет прекращен с сообщением о необработанном исключении.
Вызов исключений
Перехват исключений
Пропустить исключение
Если вы знаете, как его обработать и как его полностью восстановить, можно пропустить исключение.
Например, если вы получаете входящий файл, который может быть в различных форматах (JSON, YAML), вы можете попробовать проанализировать его с помощью различных средств. Если анализатор JSON создаёт исключение, которое показывает, что файл имеет некорректный формат JSON, вы пропускаете его и пробуете проанализировать через парсер YAML. Если парсер YAML также не справляется с задачей, тогда вы даёте исключению перейти на следующий уровень.
Обратите внимание, что другие исключения (например, file not found или no read permissions) будут переходить на следующий уровень и не будут обработаны конкретным исключением. Это хорошая тактика в том случае, если вы хотите использовать YAML парсер, когда анализ с помощью JSON парсера не удался.
Перезапуск исключения
Чтобы перезапустить исключение, просто напишите raise без аргументов внутри обработчика. Это позволит выполнить некоторую локальную обработку, но также пропустит исключение для обработки на верхние уровни. Здесь, функция invoke_function() выводит тип исключения в консоль и затем повторно вызывает его.
Вызов Различных Исключений
Есть несколько случаев, когда вы хотели бы вызвать другое исключение. Иногда вы хотите сгруппировать несколько различных низкоуровневых исключений в одну категорию, которая равномерно обрабатывается на более высоком уровне кода. В других случаях вам нужно преобразовать исключение на уровне пользователя и предоставить контекст конкретного приложения.
Финальное утверждение
Иногда вы хотите убедиться, что код очистки выполняется, даже если где-то по пути возникло исключение. Например, у вас может быть подключение к базе данных, которое требуется закрыть, как только вы закончите. Это неправильный способ сделать это:
Если функция query() вызывает исключение, то вызов close_db_connection() никогда не будет выполнен и подключение останется открытым. Утверждение finally всегда выполняется после всех попыток обработчика. Вот как сделать это правильно:
Вызов open_db_connection() может не вернуть подключение или вызвать исключение. В этом случае нет необходимости закрывать соединение.
Диспетчеров Контекста
Теперь, даже если process() вызывает исключение, этот файл будет закрыт правильно сразу же когда область видимости блока with завершена, независимо от того, было исключение обработано или нет.
Ведение журнала
Ведение журнала обычно требуется в нетривиальных, масштабных системах. Это особенно полезно в веб-приложениях, где вы можете исправить все исключения универсальным способом: Просто записать в журнал исключение и вернуть сообщение об ошибке.
Это лучший пример, которую я рекомендую:
Если вы будете придерживаться этому шаблону,тогда (предполагаю, что вы настроили запись в журнал правильно), независимо от того, что происходит, вы будете иметь очень понятные записи в ваших журналах о что пошло не так, и будете иметь возможность исправить проблему.
Если вы повторно вызываете исключение, убедитесь что вы не записывайте в журнал повторно одну и туже ошибку на разных уровнях. Эту будет бесполезный мусор. который может запутать вас и заставить думать что произошло несколько ошибок, хотя на самом деле одна ошибка была зарегистрирована несколько раз.
Самый простой способ сделать это заключается в том, чтобы позволить всем исключениям переходить дальше (если они могут быть обработаны и пропущены ранее), и затем выполнить запись в журнал на самом верхнем уровне системы/приложения.
Sentry
Ведение журнала это возможность. Наиболее распространенные реализации которой, является использование журнала. Но, для крупномасштабных распределенных систем с сотнями, тысячами или более серверов, это не всегда лучшее решение.
Для отслеживания исключений во всей инфраструктуре, такой сервис как sentry очень полезен. Он централизует все сообщения об исключениях, и в дополнении к маршруту ошибки он добавляет состояние каждого состояния стека (значение переменных в то время, когда было вызвано исключение). Он также предоставляет приятный интерфейс с панелью мониторинга, отчетами и способами получать сообщения по нескольким проектам сразу. Он предоставляется с открытым исходным кодом, так что вы можете запустить свой собственный сервер или оформить подписку на предустановленную версию.
Работа с временной ошибкой
Некоторые ошибки являются временными, в частности при работе с распределенными системами. Система, которая начинает ругаться при первом признаке ошибки не очень полезна.
Если ваш код получает доступ к удаленной системе, которая не отвечает, традиционное решение, это таймауты, но иногда случается не каждая система разработана с таймаутами. Таймауты, не всегда удобны для калибровки при изменении условий.
Другой подход заключается в том, чтобы быстро получить ошибку и затем повторить попытку. Преимущество в том, что если цель реагирует быстро, то вам не придется тратить много времени находясь в режиме ожидания и можно реагировать незамедлительно. Но если это сделать не удалось, вы можете повторять запрос несколько раз до тех пор, пока вы не решите, что ресурс действительно недоступен и вызовете исключение. В следующем разделе я расскажу об оформителе, который может сделать это для вас.
Полезные оформители
Журнал ошибок
Вот пример простой реализации. Оформитель исключает объект logger. Когда он оформляет функцию и функция вызвана, он обработает вызов в блоке try-except, и если там было исключение сделает запись в журнал и наконец повторно вызовет исключение.
Вот пример, как его использовать:
Retrier
Здесь, очень хорошая реализация @retry оформителя.
Заключение
Обработка ошибок имеет решающее значение для пользователей и разработчиков. Python предоставляет отличную поддержку на уровне языка и стандартной библиотеки для обработки ошибок на основе исключений. Следуя рекомендациям старательно, вы можете преодолеть этот аспект, которым так часто пренебрегают.
Неверный синтаксис в Python: общие причины SyntaxError
Python известен своим простым синтаксисом. Однако, когда вы изучаете Python впервые или когда вы пришли к Python, имея солидный опыт работы с другим языком программирования, вы можете столкнуться с некоторыми вещами, которые Python не допускает. Если вы когда-либо получали ошибку SyntaxError при попытке запустить код Python. Здесь вы увидите распространенные примеры недопустимого синтаксиса в Python и узнаете, как решать эти проблемы.
К концу урока вы сможете:
Содержание
Ошибочный синтаксис в Python
Когда вы запускаете свой код Python, интерпретатор сначала анализирует его, чтобы преобразовать в байт-код Python, который затем выполняет. Интерпретатор обнаружит любой недопустимый синтаксис в Python на этом первом этапе выполнения программы, также известном как этап синтаксического анализа. Если интерпретатор не может успешно проанализировать ваш код Python, то это означает, что где-то в коде вы использовали неверный синтаксис. Интерпретатор попытается показать вам, где произошла эта ошибка.
Когда вы впервые изучаете Python, может быть неприятно получить SyntaxError. Python попытается помочь вам определить неправильный синтаксис в вашем коде, но трассировка, которую он предоставляет, может немного сбивать с толку. Иногда код, на который он указывает, совершенно нормален.
Примечание. Если ваш код синтаксически правильный, вы можете получить другие исключения, которые не являются SyntaxError. Чтобы узнать больше о других исключениях Python и о том, как с ними обращаться, ознакомьтесь со статьей «Исключения Python: Введение».
Исключение SyntaxError и трассировка
Когда интерпретатор обнаруживает недопустимый синтаксис в коде Python, он вызывает исключение SyntaxError и предоставляет обратную трассировку с некоторой полезной информацией, которая поможет вам отладить ошибку. Вот код, который содержит недопустимый синтаксис в Python:
Обратите внимание, что сообщение трассировки обнаруживает ошибку в строке 5, а не в строке 4. Интерпретатор Python пытается указать, где находится недопустимый синтаксис. Однако на самом деле он может указывать только на то, где впервые заметил проблему. Когда вы получаете трассировку SyntaxError и код, на который указывает трассировка, выглядит нормально,тогда вы захотите начать движение назад по коду, пока не сможете определить, что не так.
В приведенном выше примере нет проблем с пропуском запятой, в зависимости от того, что идет после нее. Например, нет проблем с пропущенной запятой после слова michael в строке 5. Но как только интерпретатор сталкивается с чем-то, что не имеет смысла, он может указать вам только на первое, что он обнаружит, чего он не может понять.
Примечание. В этом руководстве предполагается, что вы знакомы с основами трассировки Python. Чтобы узнать больше о трассировке Python и о том, как ее читать, ознакомьтесь с разделами «Понимание трассировки Python» и «Получение максимальной отдачи от трассировки Python».
Есть несколько элементов трассировки SyntaxError, которые могут помочь вам определить, где в вашем коде находится недопустимый синтаксис:
В приведенном выше примере имя файла было theofficefacts.py, номер строки был 5, а курсор указывал на закрывающую кавычку словарного ключа michael. Трассировка SyntaxError может не указывать на настоящую проблему, но она укажет на первое место, где интерпретатор не может понять синтаксис.
Есть два других исключения, которые могут вызвать Python. Они эквивалентны SyntaxError, но имеют разные имена:
Оба эти исключения наследуются от класса SyntaxError, но это особые случаи, когда речь идет об отступах. Ошибка IndentationError возникает, когда уровни отступа вашего кода не совпадают. Ошибка TabError возникает, когда в вашем коде используются как табуляции, так и пробелы в одном файле. Вы подробнее рассмотрите эти исключения в следующем разделе.
Общие проблемы синтаксиса
Когда вы впервые сталкиваетесь с SyntaxError, полезно знать, почему возникла проблема и что вы можете сделать, чтобы исправить недопустимый синтаксис в вашем коде Python. В разделах ниже вы увидите некоторые из наиболее распространенных причин, по которым может возникать SyntaxError, и способы их устранения.
Неправильное использование оператора присваивания (=)
В Python есть несколько случаев, когда вы не можете назначать объекты. Некоторые примеры присваиваются литералам и вызовам функций. В блоке кода ниже вы можете увидеть несколько примеров, которые пытаются это сделать, и результирующие трассировки SyntaxError:
Второй и третий примеры пытаются присвоить литералам строку и целое число. То же правило верно и для других буквальных значений. Снова,сообщения трассировки указывают, что проблема возникает при попытке присвоить значение литералу.
Примечание. В приведенных выше примерах отсутствует повторяющаяся строка кода и курсор (^), указывающий на проблему в трассировке. Исключение и трассировка, которые вы видите, будут другими, когда вы находитесь в REPL и пытаетесь выполнить этот код из файла. Если бы этот код был в файле, вы бы получили повторяющуюся строку кода и курсор, указывающий на проблему, как вы видели в других случаях в этом уроке.
Скорее всего, вы не собираетесь присвоить значение литералу или вызову функции. Например, это может произойти, если вы случайно оставите лишний знак равенства (=), который превратит присвоение в сравнение. Сравнение, как вы можете видеть ниже, было бы справедливым:
В большинстве случаев, когда Python сообщает вам, что вы назначаете что-то, что не может быть назначено, вы сначала можете проверить, чтобы убедиться, что оператор не должен быть логическим выражением. Вы также можете столкнуться с этой проблемой, когда пытаетесь присвоить значение ключевому слову Python, о чем вы узнаете в следующем разделе.
Ошибочное написание, отсутствие или неправильное использование ключевых слов Python
Ключевые слова Python — это набор защищенных слов, которые имеют особое значение в Python. Это слова, которые нельзя использовать в качестве идентификаторов, переменных или имен функций в коде. Они являются частью языка и могут использоваться только в том контексте, который позволяет Python.
Есть три распространенных способа ошибочного использования ключевых слов:
Если вы неправильно написали ключевое слово в коде Python, вы получите ошибку SyntaxError. Например, вот что произойдет, если вы неправильно напишете ключевое слово для:
В сообщении написано SyntaxError: недопустимый синтаксис, но это не очень помогает. Отслеживание указывает на первое место, где Python мог обнаружить, что что-то не так. Чтобы исправить эту ошибку, убедитесь, что все ключевые слова Python написаны правильно.
Еще одна распространенная проблема с ключевыми словами — это когда вы их вообще пропускаете:
Вы также можете неправильно использовать защищенное ключевое слово 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 это встроенная функция, которой можно присвоить значения.
Вы можете запустить следующий код, чтобы увидеть список ключевых слов в любой версии Python, которую вы используете:
Ключевое слово также предоставляет полезное ключевое слово keyword.iskeyword(). Если вам просто нужен быстрый способ проверить передаваемую переменную, вы можете использовать следующий однострочник:
Этот код быстро скажет вам, является ли идентификатор, который вы пытаетесь использовать, ключевым словом или нет.
Отсутствуют круглые скобки, квадратные скобки и кавычки
Часто причиной неправильного синтаксиса в коде Python является пропущенная или несоответствующая закрывающая круглая или квадратная скобка, или цитата. Их может быть трудно обнаружить в очень длинных строках вложенных скобок или в более длинных многострочных блоках. Вы можете обнаружить несоответствующие или отсутствующие кавычки с помощью трассировки Python:
Еще одна распространенная ошибка — забыть закрыть строку. Как с двойными кавычками, так и с одинарными строками в кавычках, ситуация и трассировка одинаковы:
На этот раз курсор в трассировке указывает прямо на код проблемы. Сообщение SyntaxError EOL while scanning string literal является немного более конкретным и полезным для определения проблемы. Это означает, что интерпретатор Python дошел до конца строки (EOL) до того, как открытая строка была закрыта. Чтобы исправить это, закройте строку кавычкой, которая соответствует той, которую вы использовали для ее начала. В этом случае это будет двойная кавычка ( » ).
Кавычки, отсутствующие в операторах внутри f‑строки, также могут привести к неверному синтаксису в Python:
Здесь в ссылке на словарь возрастов внутри напечатанной f‑строки отсутствует закрывающая двойная кавычка из ключевой ссылки. Результирующая трассировка выглядит следующим образом:
Python идентифицирует проблему и сообщает вам, что она существует внутри f‑строки. Сообщение f-string: unterminated string также указывает, в чем проблема. Каретка в этом случае указывает только на начало f‑строки.
Это может быть не так полезно, как если бы курсор указывает на проблемную область f‑строки, но это сужает область, где вам нужно искать. Где-то внутри этой f‑строки есть незавершенная фраза. Вам просто нужно узнать где. Чтобы решить эту проблему, убедитесь, что присутствуют все внутренние кавычки и скобки f‑строки.
То же самое с отсутствием круглых или квадратных скобок. Если вы, например, опустите закрывающую квадратную скобку в списке, Python заметит это и укажет на нее. Однако есть несколько вариантов этого. Первый — убрать закрывающую скобку из списка:
Когда вы запустите этот код, вам сообщат, что возникла проблема с вызовом print() :
Теперь у вас другая трассировка:
В предыдущем примере 3 и print(foo()) были объединены как один элемент, но здесь вы видите запятую, разделяющую их. Теперь вызов print(foo()) добавляется как четвертый элемент списка, и Python достигает конца файла без закрывающей скобки. Трассировка сообщает вам, что Python дошел до конца файла (EOF), но он ожидал чего-то другого.
В этом примере Python ожидал закрывающую скобку ( ] ), но повторяющаяся строка и курсор не очень полезны. Python не может определить отсутствие скобок. Иногда единственное, что вы можете сделать, — это начать с курсора и двигаться назад, пока не сможете определить, что отсутствует, а что нет.
Ошибочный синтаксис словаря
Ранее вы видели, что вы можете получить SyntaxError, если оставите запятую в элементе словаря. Другой формой недопустимого синтаксиса со словарями Python является использование знака равенства ( = ) для разделения ключей и значений вместо двоеточия:
Еще раз, это сообщение об ошибке не очень помогает. Однако повторяющаяся линия и курсор очень полезны! Они указывают прямо на проблемного персонажа.
Вы можете использовать dict() для определения словаря, если этот синтаксис более полезен.
Использование неправильного отступа
Есть два подкласса SyntaxError, которые конкретно решают проблемы с отступами:
В то время как другие языки программирования используют фигурные скобки для обозначения блоков кода, Python использует пробелы. Это означает, что Python ожидает, что пробелы в вашем коде будут вести себя предсказуемо. Он вызовет ошибку IndentationError, если в блоке кода есть строка с неправильным количеством пробелов:
Хотя трассировка очень похожа на трассировку SyntaxError, на самом деле это ошибка IndentationError. Сообщение об ошибке также очень полезно. Он сообщает вам, что уровень отступа строки не соответствует ни одному уровню отступа. Другими словами, print(‘done’) имеет отступ в 2 пробела, но Python не может найти никакой другой строки кода, соответствующей этому уровню отступа. Это можно быстро исправить, убедившись, что код соответствует ожидаемому уровню отступа.
Другой тип SyntaxError — это TabError, который вы будете видеть всякий раз, когда есть строка, содержащая табуляторы или пробелы для ее отступа,в то время как остальная часть файла содержит другой. Это может быть скрыто, пока Python не укажет вам на это!
Если размер табуляции такой же, как и количество пробелов на каждом уровне отступа, может показаться, что все строки находятся на одном уровне. Однако, если одна строка имеет отступ с использованием пробелов, а другая — с помощью табуляции,тогда Python укажет на это как на проблему:
Здесь строка 5 имеет отступ с табуляции вместо 4 пробелов. Этот блок кода может выглядеть идеально для вас или может выглядеть совершенно неправильно, в зависимости от настроек вашей системы.
Однако Python сразу же заметит проблему. Но прежде чем запустить код, чтобы увидеть, что Python скажет вам об ошибке, возможно, вам будет полезно увидеть пример того, как выглядит код при разных настройках ширины вкладки:
Обратите внимание на разницу в отображении между тремя приведенными выше примерами. Большая часть кода использует 4 пробела для каждого уровня отступа, но в строке 5 во всех трех примерах используется одна табуляция. Ширина вкладки изменяется в зависимости от настройки ширины вкладки:
Когда вы запустите код, вы получите следующую ошибку и трассировку:
Обратите внимание на TabError вместо обычного SyntaxError. Python указывает на проблемную строку и выдает полезное сообщение об ошибке. Он четко говорит о том, что в одном файле для отступов используется смесь табуляции и пробелов.
Определение и вызов функций
Вы можете столкнуться с недопустимым синтаксисом в Python при определении или вызове функций. Например, вы увидите SyntaxError, если используете точку с запятой вместо двоеточия в конце определения функции:
Отслеживание здесь очень полезно, поскольку курсор указывает прямо на проблемный символ. Вы можете устранить этот недопустимый синтаксис в Python, заменив точку с запятой двоеточием.
Кроме того, аргументы ключевых слов как в определениях функций, так и в вызовах функций должны быть в правильном порядке. Аргументы ключевого слова всегда идут после позиционных аргументов. Несоблюдение этого порядка приведет к ошибке SyntaxError:
Здесь, опять же, сообщение об ошибке очень помогает, говоря вам, что именно не так с линией.
Изменение версий Python
Иногда код, который отлично работает в одной версии Python, ломается в более новой версии. Это связано с официальными изменениями синтаксиса языка. Наиболее известным примером этого является оператор печати, который превратился из ключевого слова в Python 2 во встроенную функцию в Python 3:
Другая проблема, с которой вы можете столкнуться, — это когда вы читаете или изучаете синтаксис, который является допустимым синтаксисом в более новой версии 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 и способы решения этих проблем. Это не только ускорит ваш рабочий процесс, но и сделает вас более полезным рецензентом кода!
Ошибка SyntaxError при изучении Python может быть неприятной,но теперь вы знаете, как понимать сообщения трассировки и с какими формами недопустимого синтаксиса в Python вы можете столкнуться. В следующий раз, когда вы получите SyntaxError, вы будете лучше подготовлены, чтобы быстро исправить проблему!