Как найти ошибку в программе на питоне

Трассировка (traceback) – это вывод Python. Он немного пугает начинающих разработчиков, но каждый профессионал сталкивается с проблемами в процессе исполнения кода. И трассировка помогает их эффективно разрешить. Traceback, в принципе, – хорошо, поскольку позволяет пользователю исправить причину, по которой возникла проблема при создании приложения.

Понятие трассировки и зачем она нужна?

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

Под трассировкой подразумевается отчет о том, какие вызовы выполненных функций в данный момент времени.

Вообще, встречаются разные вариации этого слова. Можно встретить названия «трассировка стека», обратная трассировка», и так далее. Но мы для простоты понимания будем использовать слово «трассировка» или английское слово «traceback», которое означает то же самое.

Как найти ошибку в коде?

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

def say_hello(man): print(‘Привет, ‘ + wrong_variable) say_hello(‘Иван’)

Здесь say_hello() вызывается с параметром man . Тем не менее, в say_hello() данное имя переменной не используется. Причиной тому служит то, что оно написано по-другому: wrong_variable в вызове print() .

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

После запуска этого приложения будет получена следующая трассировка.

Traceback (most recent call last): File «/home/test.py», line 4, in say_hello(‘Иван’) File «/home/test.py», line 2, in say_hello print(‘Привет, ‘ + wrong_variable) NameError: name ‘wrong_variable’ is not defined Process finished with exit code 1

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

Прошлые строчки из traceback говорят, какой конкретно код вызвал это исключение.

В traceback, бывшем ранее, исключение NameError . Она говорит о том, что есть отсылка к определенному имени, не определенного до того момента, как исполнялся этот код. В нашем случае ссылка осуществляется на wrong_variable .

Последняя строчка имеет достаточное количество данных для того, чтобы у вас была возможность решить эту проблему. Поиск переменной wrong_variable и заменит ее атрибутом из функции на man . Правда, с высокой долей вероятности, в реальности придется работать со сложным кодом.

Как найти ошибку в коде Работа с отладчиком

Как понять причины ошибки?

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

Структура трассировки: особенности

Python Traceback - Как правильно исправлять ошибки в коде

Каждая трассировка имеет универсальные черты. Но все секции вывода являются важными. В этом изображении описаны несколько из них.

Рекомендация: знакомиться с трассировкой рекомендуется в последовательности снизу вверх.

  1. Поле синего цвета. Последняя строчка из трассировки – уведомление об исключении, появившемся в процессе исполнения программы. Конкретно в этом поле указывается ее название.
  2. Зеленое поле. В него включено описание ошибки. Это описание, как правило, включает полезные сведения для понимания, по какой причине эта ошибка возникла.
  3. Поле желтого цвета. Немного ранее в трассировке хранятся сведения о тех функциях, которые вызывались в программе. Они идут по направлению к верху – от самых поздних до тех, которые были раньше всего. Такие вызовы являют собой двухстрочные вводы для всех вызовов. Причем первая строчка всех вызовов включает такие данные, как имя того файла, в котором появилась ошибка, номер строки, название модуля. Каждая из этих деталей позволяет понять, в каком конкретно месте может быть найден код.
  4. Красное подчеркивание. Вторая строка данных вызовов включает непосредственно тот код, при выполнении которого было вызвано исключение.

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

Python 3.7.4 (default, Jul 16 2019, 07:12:58) [GCC 9.1.0] on linux Type «help», «copyright», «credits» or «license» for more information. >>> >>> >>> def say_hello(man): . print(‘Привет, ‘ + wrong_variable) . >>> say_hello(‘Иван’) Traceback (most recent call last): File «», line 1, in File «», line 2, in say_hello NameError: name ‘wrong_variable’ is not defined

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

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

Почему было сделано так, чтобы трассировка шла вверх? Дело в том, что трассировка завершается в конце выдачи. Это облегчает структурирование прочтение вывода и разобраться, в чем ошибка.

Примеры кода с выводом трассировки

Изучение конкретных примеров трассировок позволяет лучше разобраться в том, какие сведения в них представлены и как их применять.

Читайте также:
Как узнать модель материнской платы программа

Код, который мы покажем ниже, применяется в примерах для иллюстрации данных, которые предоставляются в трассировке.

Как найти ошибку в моем скрипте (python)?

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

def Simple(n): h=2 while n > h: if n%h != 0: itog = «True» else: itog = «False» break h = h+1 if itog == «True»: print (» — Простое число».format(n)) else: print(» — Сложное число».format(n)) n = int(input(«Введите число:n»)) while n > 1: Simple(n) n = n — 1

Программа работает, но в конце пишет:
Traceback (most recent call last):
File «C:Python33exsimple_2.py», line 18, in
Simple(n)
File «C:Python33exsimple_2.py», line 12, in Simple
if itog == «True»:
UnboundLocalError: local variable ‘itog’ referenced before assignment
Помогите исправить ошибку, а то я не понял в чем ошибка..

  • Вопрос задан более трёх лет назад
  • 3804 просмотра

Комментировать
Решения вопроса 1

def Simple(n): h=2 itog = False while n > h: if n%h != 0: itog = True else: break h = h+1 if itog == «True»: print (» — Простое число».format(n)) else: print(» — Сложное число».format(n)) n = int(input(«Введите число:n»)) while n > 1: Simple(n) n = n — 1

P.S. Как уже написали выше, вместо строк нужно использовать True/False без кавычек.

P.P.S. Ещё пара замечаний:

1. Если тип переменной — логический (boolean), то можно вместо
if itog == True
использовать просто
if itog

2. Обычно функции (процедуры) в Питоне пишутся со строчной буквы (under_score-нотация). С заглавной (CamelCase) принято именовать классы.

Ответ написан более трёх лет назад
Нравится 1 1 комментарий

tsarevfs

Источник: qna.habr.com

Модуль Traceback в Python: трассировка стека

Python возвращает Traceback, когда в коде возникает исключение. Результат Traceback может быть довольно непреодолимым, если мы просматриваем его впервые или не знаем, какое сообщение он нам передает.

Введение в Traceback в Python

Однако Traceback на языке программирования Python содержит множество данных, которые могут помочь нам диагностировать и исправить причину возникновения исключения в коде. Чтобы стать хорошим программистом в Python, необходимо знать какие данные предоставляет трассировка.

В данном руководстве мы обсудим модуль Traceback на языке программирования Python и научимся распознавать несколько наиболее частых обратных связей.

Понимание Traceback на языке программирования Python

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

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

# File name: pytrace.py # defining a custom function def welcome( name ): # printing some message print( «Hello, » + nam ) # using ‘nam’ instead of ‘name’ print( «Welcome to the Python program!») # calling the function welcome( «James» )
Traceback(most recent call last): File «D:Pythonpytrace.py», line 10, in welcome( «James» ) File «D:Pythonpytrace.py», line 6, in welcome print( «Hello, » + nam ) # using ‘nam’ instead of ‘name’ NameError: name ‘nam’ is not defined

В приведенном выше фрагменте кода мы определили настраиваемую функцию с именем welcome, которая принимает параметр как «name». Однако при печати некоторых сообщений внутри функции мы неправильно написали параметр «name», заменив его на «nam». В результате Python распечатал сообщение трассировки, когда исключение возникло при вызове функции.

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

В приведенной выше трассировке исключение было NameError, которое подразумевает ссылку на какое-то имя (например, переменную, класс, функцию), которое не было определено. В следующем случае имя упоминается как «nam».

Последняя строка в приведенном выше случае содержит достаточно данных, чтобы помочь нам решить проблему. При нахождении в коде имени nam, которое написано с ошибкой, будет указано правильное написание.

Чтение трассировки в Python

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

Трассировка Python делится на несколько разделов. Каждый раздел имеет свою важность. Давайте рассмотрим следующую трассировку, показанную ниже:

Traceback (most recent call last): File «D:Pythonpytrace.py», line 10, in welcome( «James» ) File «D:Pythonpytrace.py», line 6, in welcome print( «Hello, » + nam ) # using ‘nam’ instead of ‘name’ NameError: name ‘nam’ is not defined

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

  1. Синий блок: последняя строка, выделенная синим цветом, означает строку сообщения об ошибке. Эта строка состоит из имени возникшего исключения.
  2. Зеленый блок: после названия исключения следует сообщение об ошибке. Это сообщение обычно состоит из ценных данных о причине возникшего исключения.
  3. Желтый блок: желтый блок содержит различные вызовы функции, движущиеся снизу вверх, от самых первых до самых последних. Эти вызовы обозначаются с помощью двухстрочных записей для каждого вызова. Первая строка каждого вызова состоит из таких данных, как имя файла, номер строки и имя модуля, которые указывают, где можно найти код.
  4. Жирные линии: жирные линии являются второй строкой для этих вызовов, состоящей из фактического фрагмента обработанного кода.

Есть некоторые различия между выводом трассировки, когда код выполняется в командной строке, и REPL. Давайте рассмотрим выполнение того же примера в REPL и разберемся с выводом трассировки.

>>> def welcome( name ): . print( «Hello, » + nam ) . print( «Welcome to the Python program!») . >>> welcome( «James» ) Traceback(most recent call last): File «», line 1, in File «», line 2, in welcome NameError: name ‘nam’ is not defined

Читайте также:
Программа склад приход расход остаток

Как мы можем наблюдать в приведенном выше фрагменте кода REPL, сообщение трассировки возвращает “” вместо имени (имен) файла, потому что мы ввели код через стандартный ввод. Более того, выполняемые строки кода не отображаются в сообщении трассировки.

Примечание: если некоторые из нас любят просматривать трассировки стека на разных языках программирования, то будет заметна разница в том, как трассировка выглядит на языке программирования Python. Большинство языков возвращают исключение вверху, а затем идут сверху вниз, от самых последних вызовов к наименее недавним.

В то время как в Python трассировку следует читать снизу вверх. Это очень удобно, так как при возврате трассировки терминал обычно оказывается внизу вывода, предоставляя нам идеальное место для начала чтения трассировки.

Понимание некоторых распространенных трассировок в Python

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

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

AttributeError

Исключение, известное как AttributeError, возникает при попытке доступа к атрибуту объекта, который не имеет этого определенного атрибута. В документации Python описывается, когда возникает исключение AttributeError.

Это исключение возникает при сбое ссылки или присвоения атрибута.

Давайте рассмотрим следующий пример, в котором возникло исключение AttributeError.

# defining a variable my_int = 10 print(my_int.an_attribute)
Traceback(most recent call last): File «D:Pythonpytrace.py», line 2, in print(my_int.an_attribute) AttributeError: ‘int’ object has no attribute ‘an_attribute’

В приведенном выше фрагменте кода мы определили целое число и попытались получить доступ к его атрибуту. Однако, когда мы выполняли программу, она вызывала исключение AttributeError, в котором говорилось, что конкретный тип объекта, int в приведенном выше случае, не имеет доступа к атрибуту, то есть an_attribute в этом случае. Просмотр исключения AttributeError в строке сообщения об ошибке может помочь нам определить атрибут, к которому мы пытались получить доступ, и найти способы его исправления.

Как правило, всякий раз, когда возникает подобное исключение, это означает, что мы, вероятно, имеем дело с экземпляром, который не является типом, который мы искали.

Давайте рассмотрим еще один пример для лучшего понимания:

# defining a list my_list =( 10, 20 ) # using the ‘append()’ method in the list my_list.append( 30 ) # printing the final list print( my_list )
Traceback(most recent call last): File «D:Pythonpytrace.py», line 5, in my_list.append( 30 ) AttributeError: ‘tuple’ object has no attribute ‘append’

В приведенном выше фрагменте кода мы определили список и использовали метод append() для добавления еще одного элемента в список. Однако в результате мы могли бы ожидать, что my_list будет иметь тип list, который содержит метод, известный как append(). Когда мы получили исключение AttributeError, мы заметили, что оно было вызвано при вызове функции append(), которая выразила нам, что мы не работаем с типом объекта, который искали.

Как правило, это происходит, когда мы ищем объект, который должен быть возвращен из вызова метода или функции, как определенный тип, но в конечном итоге мы остаемся с объектом типа None. В приведенном выше сценарии в строке сообщения об ошибке будет отображаться AttributeError: объект «NoneType» не имеет атрибута «append».

ImportError

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

Это исключение возникает всякий раз, когда оператору import трудно загрузить библиотеку или модуль. Более того, он вызывается всякий раз, когда “from list” в from … import содержит имя, которое не может быть обнаружено.

Давайте рассмотрим пример, демонстрирующий, как возникают ImportError и ModuleNotFoundError.

# importing a library or module import xyz from collections import xyz
# Output for the first line Traceback(most recent call last): File «D:Pythonpytrace.py», line 2, in import xyz ModuleNotFoundError: No module named ‘xyz’ # Output for the second line Traceback(most recent call last): File «D:Pythonpytrace.py», line 3, in from collections import xyz ImportError: cannot import name ‘xyz’ from ‘collections'(D:Python39libcollections__init__.py)

В приведенном выше фрагменте кода мы попытались импортировать несуществующую библиотеку или модуль xyz, что привело к возникновению исключения ModuleNotFoundError. С другой стороны, когда мы попытались импортировать модуль xyz, который не существует, из библиотеки коллекций, которая существует, программа вызвала исключение ImportError. Строки сообщения об ошибке в нижней части трассировки показывают нам, какая конкретная вещь не может быть импортирована, и в обоих вышеупомянутых случаях это xyz.

IndexError

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

Это исключение возникает всякий раз, когда нижний индекс ряда или последовательности выходит за пределы допустимого диапазона.

Давайте рассмотрим следующий пример, демонстрирующий, как возникает исключение IndexError.

# defining a list my_list = [ «Apple», «Peaches», «Mango», «Banana» ] # printing the element of the list print( my_list[ 4 ] )
Traceback(most recent call last): File «D:Pythonpytrace.py», line 5, in print( my_list[ 4 ] ) IndexError: list index out of range

В приведенном выше фрагменте кода мы определили список как my_list, содержащий четыре элемента. Однако, когда мы попытались напечатать элемент с номером индекса 5, программа вызвала исключение IndexError.

Сообщение об ошибке для исключения IndexError не дает нам надлежащих сведений. Мы можем заметить, что у нас есть ссылка на последовательность, то есть вне диапазона в дополнение к типу последовательности, список в следующем сценарии. Вместе с остальной частью трассировки этих данных обычно достаточно, чтобы помочь нам быстро распознать, как решить проблему.

Читайте также:
На какой программе стирать куртки в машине бош

KeyError

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

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

# defining a dictionary mydict = # accessing a key out of the dictionary print( mydict[‘Sam’] )
Traceback(most recent call last): File «D:Pythonpytrace.py», line 5, in print( mydict[‘Sam’] ) KeyError: ‘Sam’

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

NameError

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

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

# defining a function def myself( name ): print(«My name is», nam) # Calling the function myself( «Robin» )
Traceback(most recent call last): File «D:Pythonpytrace.py», line 6, in myself( «Robin» ) File «D:Pythonpytrace.py», line 3, in myself print(«My name is», nam) NameError: name ‘nam’ is not defined

В приведенном выше примере мы определили функцию myself(), которая принимает аргумент name. Однако мы неправильно написали имя с nam в следующей строке при печати некоторых операторов.

Затем мы вызвали функцию. В результате программа вызвала исключение NameError, поскольку имя «nam» не определено в программе.

SyntaxError

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

Давайте рассмотрим пример, иллюстрирующий, как возникает исключение SyntaxError.

# defining a function def myself( name ) print(«My name is», nam) # Calling the function myself( «Robin» )
File «D:Pythonpytrace.py», line 2 def myself( name ) ^ SyntaxError: invalid syntax

В приведенном выше синтаксисе мы определили функцию myself(), но забыли поставить двоеточие «:» после определения функции. В результате, когда мы выполнили функцию, программа вызвала исключение SyntaxError, сообщив о проблеме с синтаксисом программы. Знак ^(каретка) под строкой кода указывает на местонахождение проблемы.

Более того, мы можем заметить, что в сообщении трассировки SyntaxError не отображается обычная первая строка с надписью «Traceback (most recent call last):». Это связано с тем, что исключение SyntaxError возникает, когда Python пытается проанализировать строку кода, а строки кода не обрабатываются буквально.

TypeError

Исключение, также известное как TypeError, возникает всякий раз, когда синтаксис пытается выполнить некоторую функцию с экземпляром, который не может выполнить эту функцию, например, попытка добавить целое число в строку или вызов функции len() для объекта, длина которого не указана. В документации Python указано, когда возникает исключение TypeError: это исключение возникает всякий раз, когда функция или операция применяется к объекту неправильного типа.

Давайте рассмотрим следующий пример, демонстрирующий, как возникает исключение TypeError.

# defining some variables myint = 10 mystr = ’10’ # performing addition on objects of different types myadd = myint + mystr # printing the result print(«Result:», myadd)
Traceback(most recent call last): File «D:Pythonpytrace.py», line 4, in myadd = myint + mystr TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’

В приведенном выше примере мы определили две переменные как одно целое число и одну строку. Затем мы выполнили операцию сложения этих переменных и попытались распечатать результат. Однако программа вернула исключение TypeError, когда мы попытались добавить целочисленное значение к строковому значению.

Точно так же это исключение возникает, когда мы использовали функцию len() для типа данных int.

Давайте рассмотрим следующий пример, иллюстрирующий то же самое.

# defining the variable myint = 10 # finding length of the object of type ‘int’ print(«Length:», len(myint))
Traceback(most recent call last): File «D:Pythonpytrace.py», line 5, in print(«Length:», len(myint)) TypeError: object of type ‘int’ has no len()

В приведенном выше примере мы определили переменную с типом данных int и попытались выполнить функцию len() для этой переменной. Однако программа вызвала ошибку TypeError, заявив, что мы не можем выполнить функцию len() с объектом типа данных int.

ValueError

Исключение, также известное как ValueError, возникает всякий раз, когда значение объекта неверно. Это исключение похоже на исключение IndexError, поскольку значение индекса выходит за пределы диапазона последовательности в случае исключения IndexError. Напротив, исключение ValueError предназначено для более общего сценария.

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

Рассмотрим пример, основанный на исключении ValueError.

# defining the variables var1, var2, var3 = [10, 20, 30, 40]
Traceback(most recent call last): File «D:Pythonpytrace.py», line 2, in var1, var2, var3 = [10, 20, 30, 40] ValueError: too many values to unpack(expected 3)

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

Рассмотрим еще один пример, основанный на исключении ValueError.

# defining the variable var1, var2, var3, var4 = [10, 20, 30]
Traceback(most recent call last): File «D:Pythonpytrace.py», line 2, in var1, var2, var3, var4 = [10, 20, 30] ValueError: not enough values to unpack(expected 4, got 3)

В приведенном выше синтаксисе мы попытались распаковать слишком много значений. В результате программа возвращает исключение ValueError, сообщая, что недостаточно значений для распаковки (ожидалось 4, получено 3).

Источник: pythonpip.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru