- the
file "<stdin>", line 1, in <module>Error in Python - Resolve the
File "<stdin>", line 1, in <module>Error in Python - Conclusion

Errors are something that we often encounter while coding in any particular programming language. However, there are mainly three types of errors: syntax, logical, and runtime.
In this article, we will be discussing the most common syntax error that people face, which is the File "<stdin>", line 1, in <module> error. Let us see why this error occurs and how to resolve it in Python.
the file "<stdin>", line 1, in <module> Error in Python
Errors are unexpected situations that the programmers commit that result in the unusual working of the program. As discussed earlier, there are mainly three types of errors: Syntax, Logical, and Runtime.
However, we will mainly be concerned about a particular syntax error File "<stdin>", line 1, in <module> in this article that beginners or even experienced professionals often encounter while programming in Python.
Syntax errors occur when there is a problem in the program’s syntax. For example, using a keyword as a variable, incorrect indentation of the code, etc.
Therefore, this error mainly occurs if we use invalid syntax in our program.
The error File "<stdin>", line 1, in <module> is also a type of syntax error that occurs whenever we have a problem with the syntax of the program while using the Python interpreter.
The error refers to a problem in line 1 of the program followed by an error message that signifies the error in the program. Moreover, it also displays a line number to indicate where to look in the code for the mentioned error.
Now, let us see some examples of the error File "<stdin>", line 1, in <module>.
Resolve the File "<stdin>", line 1, in <module> Error in Python
Now, we will be seeing some of the examples of the File "<stdin>", line 1, in <module> error and how this error can be resolved in Python.
Running a Python File on the Interpreter Gives the File "<stdin>", line 1, in <module> Error
When we try to run a Python file in the Python interpreter, we encounter this error below.
Below is the Python file ex1.py to be executed.
print("Hello, user!")
print("Welcome to the page,")
print("Hope you will enjoy the experience.")
However, when we try to run this ex1.py file in the interpreter, we get the following output.
>>> python ex1.py
File "<stdin>", line 1
python ex1.py
^
SyntaxError: invalid syntax
However, it occurs because the file ex1.py should not be executed on the Python interpreter but should have been done on the terminal.
Python interpreters are meant to run only valid Python statements and not the whole files. Therefore, we should use the terminal for that whenever we have to run a Python file.
However, to get back to the terminal while you are using the Python interpreter, you should either type exit() and press the Enter key to take an exit from the Python interpreter or directly press CTRL+D for exiting the Python interpreter.
Let us see how to take an exit from the Python interpreter.
Now, you must have been at the terminal. Therefore, go to the specified path on which your Python file is saved and then write python <file_name> to run your file without getting the File "<stdin>", line 1, in <module> error.
The output will appear something like below on executing the desired file.
D:poll>python ex1.py
Hello, user!
Welcome to the page,
Hope you will enjoy the experience.
In this way, we can remove the File "<stdin>", line 1, in <module> error from our program.
Invalid Syntax Statements in Python Causes the File "<stdin>", line 1, in <module> Error
The invalid syntax, such as using invalid names, division of a number by 0, etc., can also cause the File "<stdin>", line 1, in <module> error. Let us now see them in detail.
Output:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Therefore, the output shows the File "<stdin>", line 1, in <module> NameError error as the answer variable is assigned a value of x which is not defined anywhere in the program.
To resolve the issue, we need to define the variable x below the answer variable.
However, another example of the File "<stdin>", line 1, in <module> error can be the division of a number by 0. Let us have a look at it.
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
Therefore, as you can see above, the division throws the same error.
However, all the above examples are executed on the interpreter, and they work fine because they are single statements and not files. Therefore, you must remember that you can only execute valid statements on the Python interpreter, not the whole Python file.
For executing the Python files, you must use the terminal.
Moreover, the error File "<stdin>", line 1, in <module> can also be written as File "<stdin>", line 6, in <module> depending on the line number on which the error is encountered but the meaning of the error and the way to solve it remains the same.
Conclusion
In this article, we have studied the most common error that programmers often encounter while programming in Python, which is the File "<stdin>", line 1, in <module> error. This error often occurs because of executing a file in the Python interpreter or having some syntax errors in the Python code.
However, we have discussed how these errors can be resolved that are executing a Python file in a terminal instead of the interpreter in the case of a file, whereas resolving the appropriate syntax errors in the program in the case of the Python statements.
Содержание
- Заголовок
- Чтение Traceback 1
- Чтение Traceback 2
- Некоторые ошибки с примерами кода
- Ошибки в синтаксисе
- Ошибки в логике
- Контест №1
Заголовок
Создайте файл solution.py со следующим кодом:
for coord in vector: print(coord) |
Наш код подразумевает печать содержимого переменной vector.
Запустим написанный скрипт, получим следующий вывод:
$ python3 solution.py Traceback (most recent call last): File "solution.py", line 1, in <module> for coord in vector: NameError: name 'vector' is not defined
Сообщение означает, что при исполнении кода возникла ошибка.
При этом Python сообщает нам кое-что ещё.
Разберём это сообщение детально.
Чтение Traceback 1
Исходное сообщение нужно мысленно разделить на две части.
Первая часть это traceback-сообщение:
Traceback (most recent call last):
File "solution.py", line 1, in <module>
for coord in vector:
Вторая часть — сообщение о возникшей ошибке:
NameError: name 'vector' is not defined
Разберём первую часть.
Traceback в грубом переводе означает «отследить назад».
Traceback показывает последовательность/стэк вызовов, которая, в конечном итоге, вызвала ошибку.
Первая строка:
Traceback (most recent call last):
является заголовочной.
Она сообщает, что в последующих строках будет изложен стэк вызовов (он показан отступами).
Обратите внимание на сообщение в скобках, оно указывает на порядок вызовов.
В данном случае (он же случай по умолчанию) тот вызов, в котором произошла ошибка, будет в последовательности вызовов указан последним.
Вторая и третья строки:
File "solution.py", line 1, in <module> for coord in vector:
показывают информацию о вызове (в нашем случае он один).
Во-первых, здесь есть информация о файле, в котором произошёл вызов («solution.py»), затем указан номер строки, где этот вызов происходит («line 1»), в конце стоит информация о том, откуда произошёл вызов («<module>»).
В нашем случае вызов происходит непосредственно из модуля, т.е. не из функции.
Наконец, вывод содержит не только номер строки, но и саму строку «for coord in vector:».
Заключительная строка сообщения:
NameError: name 'vector' is not defined
содержит вид (тип) ошибки («NameError»), и после двоеточия содержит подсказку.
В данном случае она означает, что имя «vector» не определено.
В самом деле, если взглянуть снова на код, то можно убедиться, что мы нигде не объявили переменную «vector».
Подведём итоги.
При попытке запуска мы получили следующий вывод
$ python3 solution.py Traceback (most recent call last): File "solution.py", line 1, in <module> for coord in vector: NameError: name 'vector' is not defined
Он говорит нам о возникновении ошибки.
Эта ошибка обнаружилась интерпретатором в первой строке файла «solution.py».
Сама ошибка является ошибкой имени и указывает на необъявленное имя — «vector».
Чтение Traceback 2
Оберните код из solution.py в функцию:
def print_vector(vector): for coord in vector: print(coord) print_vector(5) |
Запустим наш код
$ python3 solution.py Traceback (most recent call last): File "solution.py", line 5, in <module> print_vector(5) File "solution.py", line 2, in print_vector for coord in vector: TypeError: 'int' object is not iterable
На этот раз сообщение об ошибке сложнее, однако структура у него та же.
Часть со стеком вызовов увеличилась:
Traceback (most recent call last):
File "solution.py", line 5, in <module>
print_vector(5)
File "solution.py", line 2, in print_vector
for coord in vector:
Поскольку «most recent call last», читать будем её сверху вниз.
Вызовов на этот раз два.
Первый вызов:
File "solution.py", line 5, in <module> print_vector(5)
Произошел в пятой строке.
Судя по строчке кода, это вызов написанной нами функции print_vector(5) с аргументом 5.
Следом за ней второй вызов:
File "solution.py", line 2, in print_vector for coord in vector:
Этот вызов происходит внутри функции print_vector, содержащейся в файле «solution.py».
Вызов находится в строке 2.
Сама же ошибка имеет вид:
TypeError: 'int' object is not iterable
Как и в первом примере, сообщение об ошибке содержит её тип и подсказку.
В нашем случае произошла ошибка типа.
В подсказке же указано, что объект типа int не является итерируемым, т.е. таким объектом, который нельзя использовать в цикле for.
Итог:
$ python3 solution.py Traceback (most recent call last): File "solution.py", line 5, in <module> print_vector(5) File "solution.py", line 2, in print_vector for coord in vector: TypeError: 'int' object is not iterable
В нашем коде возникла ошибка.
Её вызвала последовательность вызовов.
Первый вызов произошел непосредственно из модуля — в строке 5 происходит вызов функции print_vector(5).
Внутри этой функции ошибка возникла в строчке 2, содержащей проход по циклу.
Сообщение об ошибке означает, что итерироваться по объекту типа int нельзя.
В нашем случае мы вызвали функцию print_vector от числа (от 5).
Некоторые ошибки с примерами кода
Ошибки в синтаксисе
Наиболее частая ошибка, которая возникает в программах на Python — SyntaxError: когда какое-то утверждение записано не по правилам языка, например:
$ python3 >>> print "hello" File "<stdin>", line 1 print "hello" ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print("hello")?
Тот же тип ошибки возникнет, если забыть поставить двоеточие в цикле:
$ python3 >>> for i in range(5) File "<stdin>", line 1 for i in range(5) ^ SyntaxError: invalid syntax
При неправильном использовании пробелов и табуляций в начале строки возникает IndentationError:
$ python3 >>> for i in range(5): print(i) File "<stdin>", line 2 print(i) ^ IndentationError: expected an indented block
А теперь посмотрим, что будет, если в первой строке цикла воспользоваться пробелами, а во второй — табуляцией:
$ python3 >>> for i in range(5): print(i) # здесь пробелы print(i**2) # здесь табуляция File "<stdin>", line 3 print(i**2) ^ TabError: inconsistent use of tabs and spaces in indentation
NameError возникает при обращении к несуществующей переменной:
$ python3 >>> words = "Hello" >>> word Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'word' is not defined
Ошибки в логике
Напишем простую программу на деление с остатком и сохраним как sample.py:
n = input() m = input() print(n % m)
и запустим её:
$ python3 sample.py 5 3 Traceback (most recent call last): File "sample.py", line 3, in <module> print(n % m) TypeError: not all arguments converted during string formatting
Возникла ошибка TypeError, которая сообщает о неподходящем типе данных. Исправим программу:
n = int(input()) m = int(input()) print(n % m)
запустим на неподходящих данных:
$ python3 sample.py xyz Traceback (most recent call last): File "sample.py", line 1, in <module> n = int(input()) ValueError: invalid literal for int() with base 10: 'xyz'
Возникнет ValueError.
Эту ошибку ещё можно воспринимать как использование значения вне области допустимых значений (ОДЗ).
Теперь запустим программу на числовых данных:
$ python3 sample.py 1 0 Traceback (most recent call last): File "sample.py", line 3, in <module> print(n % m) ZeroDivisionError: integer division or modulo by zero
При работе с массивами нередко возникает ошибка IndexError. Она возникает при выходе за пределы массива:
$ python3 >>> L1 = [1, 2, 3] >>> L1[3] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
Что будет, если вызвать бесконечную рекурсию? Опишем её в программе endless.py
def noend(): print("Hello!") noend() noend()
Через некоторое время после запуска возникнет RecursionError:
Traceback (most recent call last): File "endless.py", line 4, in <module> noend() File "endless.py", line 3, in noend noend() File "endless.py", line 3, in noend noend() File "endless.py", line 3, in noend noend() [Previous line repeated 993 more times] File "endless.py", line 2, in noend print("Hello!") RecursionError: maximum recursion depth exceeded while calling a Python object
Python выводит трассировку (далее traceback), когда в вашем коде появляется ошибка. Вывод traceback может быть немного пугающим, если вы видите его впервые, или не понимаете, чего от вас хотят. Однако traceback Python содержит много информации, которая может помочь вам определить и исправить причину, из-за которой в вашем коде возникла ошибка.
Содержание статьи
- Traceback — Что это такое и почему оно появляется?
- Как правильно читать трассировку?
- Обзор трассировка Python
- Подробный обзор трассировки в Python
- Обзор основных Traceback исключений в Python
- AttributeError
- ImportError
- IndexError
- KeyError
- NameError
- SyntaxError
- TypeError
- ValueError
- Логирование ошибок из Traceback
- Вывод
Понимание того, какую информацию предоставляет traceback Python является основополагающим критерием того, как стать лучшим Python программистом.
К концу данной статьи вы сможете:
- Понимать, что несет за собой traceback
- Различать основные виды traceback
- Успешно вести журнал traceback, при этом исправить ошибку
Python Traceback — Как правильно читать трассировку?
Traceback (трассировка) — это отчет, который содержит вызовы выполненных функций в вашем коде в определенный момент.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Traceback называют по разному, иногда они упоминаются как трассировка стэка, обратная трассировка, и так далее. В Python используется определение “трассировка”.
Когда ваша программа выдает ошибку, Python выводит текущую трассировку, чтобы подсказать вам, что именно пошло не так. Ниже вы увидите пример, демонстрирующий данную ситуацию:
|
def say_hello(man): print(‘Привет, ‘ + wrong_variable) say_hello(‘Иван’) |
Здесь say_hello() вызывается с параметром man. Однако, в say_hello() это имя переменной не используется. Это связано с тем, что оно написано по другому: wrong_variable в вызове print().
Обратите внимание: в данной статье подразумевается, что вы уже имеете представление об ошибках Python. Если это вам не знакомо, или вы хотите освежить память, можете ознакомиться с нашей статьей: Обработка ошибок в Python
Когда вы запускаете эту программу, вы получите следующую трассировку:
|
Traceback (most recent call last): File «/home/test.py», line 4, in <module> 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 — Как правильно понять в чем ошибка?
Трассировка Python содержит массу полезной информации, когда вам нужно определить причину ошибки, возникшей в вашем коде. В данном разделе, мы рассмотрим различные виды traceback, чтобы понять ключевые отличия информации, содержащейся в traceback.
Существует несколько секций для каждой трассировки Python, которые являются крайне важными. Диаграмма ниже описывает несколько частей:
В Python лучше всего читать трассировку снизу вверх.
- Синее поле: последняя строка из traceback — это строка уведомления об ошибке. Синий фрагмент содержит название возникшей ошибки.
- Зеленое поле: после названия ошибки идет описание ошибки. Это описание обычно содержит полезную информацию для понимания причины возникновения ошибки.
- Желтое поле: чуть выше в трассировке содержатся различные вызовы функций. Снизу вверх — от самых последних, до самых первых. Эти вызовы представлены двухстрочными вводами для каждого вызова. Первая строка каждого вызова содержит такую информацию, как название файла, номер строки и название модуля. Все они указывают на то, где может быть найден код.
- Красное подчеркивание: вторая строка этих вызовов содержит непосредственный код, который был выполнен с ошибкой.
Есть ряд отличий между выдачей трассировок, когда вы запускает код в командной строке, и между запуском кода в 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 «<stdin>», line 1, in <module> File «<stdin>», line 2, in say_hello NameError: name ‘wrong_variable’ is not defined |
Обратите внимание на то, что на месте названия файла вы увидите <stdin>. Это логично, так как вы выполнили код через стандартный ввод. Кроме этого, выполненные строки кода не отображаются в traceback.
Важно помнить: если вы привыкли видеть трассировки стэка в других языках программирования, то вы обратите внимание на явное различие с тем, как выглядит traceback в Python. Большая часть других языков программирования выводят ошибку в начале, и затем ведут сверху вниз, от недавних к последним вызовам.
Это уже обсуждалось, но все же: трассировки Python читаются снизу вверх. Это очень помогает, так как трассировка выводится в вашем терминале (или любым другим способом, которым вы читаете трассировку) и заканчивается в конце выдачи, что помогает последовательно структурировать прочтение из traceback и понять в чем ошибка.
Traceback в Python на примерах кода
Изучение отдельно взятой трассировки поможет вам лучше понять и увидеть, какая информация в ней вам дана и как её применить.
Код ниже используется в примерах для иллюстрации информации, данной в трассировке Python:
Мы запустили ниже предоставленный код в качестве примера и покажем какую информацию мы получили от трассировки.
Сохраняем данный код в файле greetings.py
|
def who_to_greet(person): return person if person else input(‘Кого приветствовать? ‘) def greet(someone, greeting=‘Здравствуйте’): print(greeting + ‘, ‘ + who_to_greet(someone)) def greet_many(people): for person in people: try: greet(person) except Exception: print(‘Привет, ‘ + person) |
Функция who_to_greet() принимает значение person и либо возвращает данное значение если оно не пустое, либо запрашивает значение от пользовательского ввода через input().
Далее, greet() берет имя для приветствия из someone, необязательное значение из greeting и вызывает print(). Также с переданным значением из someone вызывается who_to_greet().
Наконец, greet_many() выполнит итерацию по списку людей и вызовет greet(). Если при вызове greet() возникает ошибка, то выводится резервное приветствие print('hi, ' + person).
Этот код написан правильно, так что никаких ошибок быть не может при наличии правильного ввода.
Если вы добавите вызов функции greet() в конце нашего кода (которого сохранили в файл greetings.py) и дадите аргумент который он не ожидает (например, greet('Chad', greting='Хай')), то вы получите следующую трассировку:
|
$ python greetings.py Traceback (most recent call last): File «/home/greetings.py», line 19, in <module> greet(‘Chad’, greting=‘Yo’) TypeError: greet() got an unexpected keyword argument ‘greting’ |
Еще раз, в случае с трассировкой Python, лучше анализировать снизу вверх. Начиная с последней строки трассировки, вы увидите, что ошибкой является TypeError. Сообщения, которые следуют за типом ошибки, дают вам полезную информацию. Трассировка сообщает, что greet() вызван с аргументом, который не ожидался. Неизвестное название аргумента предоставляется в том числе, в нашем случае это greting.
Поднимаясь выше, вы можете видеть строку, которая привела к исключению. В данном случае, это вызов greet(), который мы добавили в конце greetings.py.
Следующая строка дает нам путь к файлу, в котором лежит код, номер строки этого файла, где вы можете найти код, и то, какой в нем модуль. В нашем случае, так как наш код не содержит никаких модулей Python, мы увидим только надпись , означающую, что этот файл является выполняемым.
С другим файлом и другим вводом, вы можете увидеть, что трассировка явно указывает вам на правильное направление, чтобы найти проблему. Следуя этой информации, мы удаляем злополучный вызов greet() в конце greetings.py, и добавляем следующий файл под названием example.py в папку:
|
from greetings import greet greet(1) |
Здесь вы настраиваете еще один файл Python, который импортирует ваш предыдущий модуль greetings.py, и используете его greet(). Вот что произойдете, если вы запустите example.py:
|
$ python example.py Traceback (most recent call last): File «/path/to/example.py», line 3, in <module> greet(1) File «/path/to/greetings.py», line 5, in greet print(greeting + ‘, ‘ + who_to_greet(someone)) TypeError: must be str, not int |
В данном случае снова возникает ошибка TypeError, но на этот раз уведомление об ошибки не очень помогает. Оно говорит о том, что где-то в коде ожидается работа со строкой, но было дано целое число.
Идя выше, вы увидите строку кода, которая выполняется. Затем файл и номер строки кода. На этот раз мы получаем имя функции, которая была выполнена — greet().
Поднимаясь к следующей выполняемой строке кода, мы видим наш проблемный вызов greet(), передающий целое число.
Иногда, после появления ошибки, другой кусок кода берет эту ошибку и также её выдает. В таких случаях, Python выдает все трассировки ошибки в том порядке, в котором они были получены, и все по тому же принципу, заканчивая на самой последней трассировке.
Так как это может сбивать с толку, рассмотрим пример. Добавим вызов greet_many() в конце greetings.py:
|
# greetings.py ... greet_many([‘Chad’, ‘Dan’, 1]) |
Это должно привести к выводу приветствия всем трем людям. Однако, если вы запустите этот код, вы увидите несколько трассировок в выдаче:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ python greetings.py Hello, Chad Hello, Dan Traceback (most recent call last): File «greetings.py», line 10, in greet_many greet(person) File «greetings.py», line 5, in greet print(greeting + ‘, ‘ + who_to_greet(someone)) TypeError: must be str, not int During handling of the above exception, another exception occurred: Traceback (most recent call last): File «greetings.py», line 14, in <module> greet_many([‘Chad’, ‘Dan’, 1]) File «greetings.py», line 12, in greet_many print(‘hi, ‘ + person) TypeError: must be str, not int |
Обратите внимание на выделенную строку, начинающуюся с “During handling in the output above”. Между всеми трассировками, вы ее увидите.
Это достаточно ясное уведомление: Пока ваш код пытался обработать предыдущую ошибку, возникла новая.
Обратите внимание: функция отображения предыдущих трассировок была добавлена в Python 3. В Python 2 вы можете получать только трассировку последней ошибки.
Вы могли видеть предыдущую ошибку, когда вызывали greet() с целым числом. Так как мы добавили 1 в список людей для приветствия, мы можем ожидать тот же результат. Однако, функция greet_many() оборачивает вызов greet() и пытается в блоке try и except. На случай, если greet() приведет к ошибке, greet_many() захочет вывести приветствие по-умолчанию.
Соответствующая часть greetings.py повторяется здесь:
|
def greet_many(people): for person in people: try: greet(person) except Exception: print(‘hi, ‘ + person) |
Когда greet() приводит к TypeError из-за неправильного ввода числа, greet_many() обрабатывает эту ошибку и пытается вывести простое приветствие. Здесь код приводит к другой, аналогичной ошибке. Он все еще пытается добавить строку и целое число.
Просмотр всей трассировки может помочь вам увидеть, что стало причиной ошибки. Иногда, когда вы получаете последнюю ошибку с последующей трассировкой, вы можете не увидеть, что пошло не так. В этих случаях, изучение предыдущих ошибок даст лучшее представление о корне проблемы.
Обзор основных Traceback исключений в Python 3
Понимание того, как читаются трассировки Python, когда ваша программа выдает ошибку, может быть очень полезным навыком, однако умение различать отдельные трассировки может заметно ускорить вашу работу.
Рассмотрим основные ошибки, с которыми вы можете сталкиваться, причины их появления и что они значат, а также информацию, которую вы можете найти в их трассировках.
Ошибка AttributeError object has no attribute [Решено]
AttributeError возникает тогда, когда вы пытаетесь получить доступ к атрибуту объекта, который не содержит определенного атрибута. Документация Python определяет, когда эта ошибка возникнет:
Возникает при вызове несуществующего атрибута или присвоение значения несуществующему атрибуту.
Пример ошибки AttributeError:
|
>>> an_int = 1 >>> an_int.an_attribute Traceback (most recent call last): File «<stdin>», line 1, in <module> AttributeError: ‘int’ object has no attribute ‘an_attribute’ |
Строка уведомления об ошибке для AttributeError говорит вам, что определенный тип объекта, в данном случае int, не имеет доступа к атрибуту, в нашем случае an_attribute. Увидев AttributeError в строке уведомления об ошибке, вы можете быстро определить, к какому атрибуту вы пытались получить доступ, и куда перейти, чтобы это исправить.
Большую часть времени, получение этой ошибки определяет, что вы возможно работаете с объектом, тип которого не является ожидаемым:
|
>>> a_list = (1, 2) >>> a_list.append(3) Traceback (most recent call last): File «<stdin>», line 1, in <module> AttributeError: ‘tuple’ object has no attribute ‘append’ |
В примере выше, вы можете ожидать, что a_list будет типом списка, который содержит метод .append(). Когда вы получаете ошибку AttributeError, и видите, что она возникла при попытке вызова .append(), это говорит о том, что вы, возможно, не работаете с типом объекта, который ожидаете.
Часто это происходит тогда, когда вы ожидаете, что объект вернется из вызова функции или метода и будет принадлежать к определенному типу, но вы получаете тип объекта None. В данном случае, строка уведомления об ошибке будет выглядеть так:
AttributeError: ‘NoneType’ object has no attribute ‘append’
Python Ошибка ImportError: No module named [Решено]
ImportError возникает, когда что-то идет не так с оператором import. Вы получите эту ошибку, или ее подкласс ModuleNotFoundError, если модуль, который вы хотите импортировать, не может быть найден, или если вы пытаетесь импортировать что-то, чего не существует во взятом модуле. Документация Python определяет, когда возникает эта ошибка:
Ошибка появляется, когда в операторе импорта возникают проблемы при попытке загрузить модуль. Также вызывается, при конструкции импорта
from listвfrom ... importимеет имя, которое невозможно найти.
Вот пример появления ImportError и ModuleNotFoundError:
|
>>> import asdf Traceback (most recent call last): File «<stdin>», line 1, in <module> ModuleNotFoundError: No module named ‘asdf’ >>> from collections import asdf Traceback (most recent call last): File «<stdin>», line 1, in <module> ImportError: cannot import name ‘asdf’ |
В примере выше, вы можете видеть, что попытка импорта модуля asdf, который не существует, приводит к ModuleNotFoundError. При попытке импорта того, что не существует (в нашем случае — asdf) из модуля, который существует (в нашем случае — collections), приводит к ImportError. Строки сообщения об ошибке трассировок указывают на то, какая вещь не может быть импортирована, в обоих случаях это asdf.
Ошибка IndexError: list index out of range [Решено]
IndexError возникает тогда, когда вы пытаетесь вернуть индекс из последовательности, такой как список или кортеж, и при этом индекс не может быть найден в последовательности. Документация Python определяет, где эта ошибка появляется:
Возникает, когда индекс последовательности находится вне диапазона.
Вот пример, который приводит к IndexError:
|
>>> a_list = [‘a’, ‘b’] >>> a_list[3] Traceback (most recent call last): File «<stdin>», line 1, in <module> IndexError: list index out of range |
Строка сообщения об ошибке для IndexError не дает вам полную информацию. Вы можете видеть, что у вас есть отсылка к последовательности, которая не доступна и то, какой тип последовательности рассматривается, в данном случае это список.
Иными словами, в списке a_list нет значения с ключом
3. Есть только значение с ключами0и1, этоaиbсоответственно.
Эта информация, в сочетании с остальной трассировкой, обычно является исчерпывающей для помощи программисту в быстром решении проблемы.
Возникает ошибка KeyError в Python 3 [Решено]
Как и в случае с IndexError, KeyError возникает, когда вы пытаетесь получить доступ к ключу, который отсутствует в отображении, как правило, это dict. Вы можете рассматривать его как IndexError, но для словарей. Из документации:
Возникает, когда ключ словаря не найден в наборе существующих ключей.
Вот пример появления ошибки KeyError:
|
>>> a_dict = [‘a’: 1, ‘w’: ‘2’] >>> a_dict[‘b’] Traceback (most recent call last): File «<stdin>», line 1, in <module> KeyError: ‘b’ |
Строка уведомления об ошибки KeyError говорит о ключе, который не может быть найден. Этого не то чтобы достаточно, но, если взять остальную часть трассировки, то у вас будет достаточно информации для решения проблемы.
Ошибка NameError: name is not defined в Python [Решено]
NameError возникает, когда вы ссылаетесь на название переменной, модуля, класса, функции, и прочего, которое не определено в вашем коде.
Документация Python дает понять, когда возникает эта ошибка NameError:
Возникает, когда локальное или глобальное название не было найдено.
В коде ниже, greet() берет параметр person. Но в самой функции, этот параметр был назван с ошибкой, persn:
|
>>> def greet(person): ... print(f‘Hello, {persn}’) >>> greet(‘World’) Traceback (most recent call last): File «<stdin>», line 1, in <module> File «<stdin>», line 2, in greet NameError: name ‘persn’ is not defined |
Строка уведомления об ошибке трассировки NameError указывает вам на название, которое мы ищем. В примере выше, это названная с ошибкой переменная или параметр функции, которые были ей переданы.
NameError также возникнет, если берется параметр, который мы назвали неправильно:
|
>>> def greet(persn): ... print(f‘Hello, {person}’) >>> greet(‘World’) Traceback (most recent call last): File «<stdin>», line 1, in <module> File «<stdin>», line 2, in greet NameError: name ‘person’ is not defined |
Здесь все выглядит так, будто вы сделали все правильно. Последняя строка, которая была выполнена, и на которую ссылается трассировка выглядит хорошо.
Если вы окажетесь в такой ситуации, то стоит пройтись по коду и найти, где переменная person была использована и определена. Так вы быстро увидите, что название параметра введено с ошибкой.
Ошибка SyntaxError: invalid syntax в Python [Решено]
Возникает, когда синтаксический анализатор обнаруживает синтаксическую ошибку.
Ниже, проблема заключается в отсутствии двоеточия, которое должно находиться в конце строки определения функции. В REPL Python, эта ошибка синтаксиса возникает сразу после нажатия Enter:
|
>>> def greet(person) File «<stdin>», line 1 def greet(person) ^ SyntaxError: invalid syntax |
Строка уведомления об ошибке SyntaxError говорит вам только, что есть проблема с синтаксисом вашего кода. Просмотр строк выше укажет вам на строку с проблемой. Каретка ^ обычно указывает на проблемное место. В нашем случае, это отсутствие двоеточия в операторе def нашей функции.
Стоит отметить, что в случае с трассировками SyntaxError, привычная первая строка Tracebak (самый последний вызов) отсутствует. Это происходит из-за того, что SyntaxError возникает, когда Python пытается парсить ваш код, но строки фактически не выполняются.
Ошибка TypeError в Python 3 [Решено]
TypeError возникает, когда ваш код пытается сделать что-либо с объектом, который не может этого выполнить, например, попытка добавить строку в целое число, или вызвать len() для объекта, в котором не определена длина.
Ошибка возникает, когда операция или функция применяется к объекту неподходящего типа.
Рассмотрим несколько примеров того, когда возникает TypeError:
|
>>> 1 + ‘1’ Traceback (most recent call last): File «<stdin>», line 1, in <module> TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’ >>> ‘1’ + 1 Traceback (most recent call last): File «<stdin>», line 1, in <module> TypeError: must be str, not int >>> len(1) Traceback (most recent call last): File «<stdin>», line 1, in <module> TypeError: object of type ‘int’ has no len() |
Указанные выше примеры возникновения TypeError приводят к строке уведомления об ошибке с разными сообщениями. Каждое из них весьма точно информирует вас о том, что пошло не так.
В первых двух примерах мы пытаемся внести строки и целые числа вместе. Однако, они немного отличаются:
- В первом примере мы пытаемся добавить
strкint. - Во втором примере мы пытаемся добавить
intкstr.
Уведомления об ошибке указывают на эти различия.
Последний пример пытается вызвать len() для int. Сообщение об ошибке говорит нам, что мы не можем сделать это с int.
Возникла ошибка ValueError в Python 3 [Решено]
ValueError возникает тогда, когда значение объекта не является корректным. Мы можем рассматривать это как IndexError, которая возникает из-за того, что значение индекса находится вне рамок последовательности, только ValueError является более обобщенным случаем.
Возникает, когда операция или функция получает аргумент, который имеет правильный тип, но неправильное значение, и ситуация не описывается более детальной ошибкой, такой как IndexError.
Вот два примера возникновения ошибки ValueError:
|
>>> a, b, c = [1, 2] Traceback (most recent call last): File «<stdin>», line 1, in <module> ValueError: not enough values to unpack (expected 3, got 2) >>> a, b = [1, 2, 3] Traceback (most recent call last): File «<stdin>», line 1, in <module> ValueError: too many values to unpack (expected 2) |
Строка уведомления об ошибке ValueError в данных примерах говорит нам в точности, в чем заключается проблема со значениями:
- В первом примере, мы пытаемся распаковать слишком много значений. Строка уведомления об ошибке даже говорит нам, где именно ожидается распаковка трех значений, но получаются только два.
- Во втором примере, проблема в том, что мы получаем слишком много значений, при этом получаем недостаточно значений для распаковки.
Логирование ошибок из Traceback в Python 3
Получение ошибки, и ее итоговой трассировки указывает на то, что вам нужно предпринять для решения проблемы. Обычно, отладка кода — это первый шаг, но иногда проблема заключается в неожиданном, или некорректном вводе. Хотя важно предусматривать такие ситуации, иногда есть смысл скрывать или игнорировать ошибку путем логирования traceback.
Рассмотрим жизненный пример кода, в котором нужно заглушить трассировки Python. В этом примере используется библиотека requests.
Файл urlcaller.py:
|
import sys import requests response = requests.get(sys.argv[1]) print(response.status_code, response.content) |
Этот код работает исправно. Когда вы запускаете этот скрипт, задавая ему URL в качестве аргумента командной строки, он откроет данный URL, и затем выведет HTTP статус кода и содержимое страницы (content) из response. Это работает даже в случае, если ответом является статус ошибки HTTP:
|
$ python urlcaller.py https://httpbin.org/status/200 200 b» $ python urlcaller.py https://httpbin.org/status/500 500 b» |
Однако, иногда данный URL не существует (ошибка 404 — страница не найдена), или сервер не работает. В таких случаях, этот скрипт приводит к ошибке ConnectionError и выводит трассировку:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ python urlcaller.py http://thisurlprobablydoesntexist.com ... During handling of the above exception, another exception occurred: Traceback (most recent call last): File «urlcaller.py», line 5, in <module> response = requests.get(sys.argv[1]) File «/path/to/requests/api.py», line 75, in get return request(‘get’, url, params=params, **kwargs) File «/path/to/requests/api.py», line 60, in request return session.request(method=method, url=url, **kwargs) File «/path/to/requests/sessions.py», line 533, in request resp = self.send(prep, **send_kwargs) File «/path/to/requests/sessions.py», line 646, in send r = adapter.send(request, **kwargs) File «/path/to/requests/adapters.py», line 516, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host=‘thisurlprobablydoesntexist.com’, port=80): Max retries exceeded with url: / (Caused by NewConnectionError(‘<urllib3.connection.HTTPConnection object at 0x7faf9d671860>: Failed to establish a new connection: [Errno -2] Name or service not known’,)) |
Трассировка Python в данном случае может быть очень длинной, и включать в себя множество других ошибок, которые в итоге приводят к ошибке ConnectionError. Если вы перейдете к трассировке последних ошибок, вы заметите, что все проблемы в коде начались на пятой строке файла urlcaller.py.
Если вы обернёте неправильную строку в блоке try и except, вы сможете найти нужную ошибку, которая позволит вашему скрипту работать с большим числом вводов:
Файл urlcaller.py:
|
try: response = requests.get(sys.argv[1]) except requests.exceptions.ConnectionError: print(—1, ‘Connection Error’) else: print(response.status_code, response.content) |
Код выше использует предложение else с блоком except.
Теперь, когда вы запускаете скрипт на URL, который приводит к ошибке ConnectionError, вы получите -1 в статусе кода и содержимое ошибки подключения:
|
$ python urlcaller.py http://thisurlprobablydoesntexist.com —1 Connection Error |
Это работает отлично. Однако, в более реалистичных системах, вам не захочется просто игнорировать ошибку и итоговую трассировку, вам скорее понадобиться внести в журнал. Ведение журнала трассировок позволит вам лучше понять, что идет не так в ваших программах.
Обратите внимание: Для более лучшего представления о системе логирования в Python вы можете ознакомиться с данным руководством тут: Логирование в Python
Вы можете вести журнал трассировки в скрипте, импортировав пакет logging, получить logger, вызвать .exception() для этого логгера в куске except блока try и except. Конечный скрипт будет выглядеть примерно так:
|
# urlcaller.py import logging import sys import requests logger = logging.getLogger(__name__) try: response = requests.get(sys.argv[1]) except requests.exceptions.ConnectionError as e: logger.exception() print(—1, ‘Connection Error’) else: print(response.status_code, response.content) |
Теперь, когда вы запускаете скрипт с проблемным URL, он будет выводить исключенные -1 и ConnectionError, но также будет вести журнал трассировки:
|
$ python urlcaller.py http://thisurlprobablydoesntexist.com ... File «/path/to/requests/adapters.py», line 516, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host=‘thisurlprobablydoesntexist.com’, port=80): Max retries exceeded with url: / (Caused by NewConnectionError(‘<urllib3.connection.HTTPConnection object at 0x7faf9d671860>: Failed to establish a new connection: [Errno -2] Name or service not known’,)) —1 Connection Error |
По умолчанию, Python будет выводить ошибки в стандартный stderr. Выглядит так, будто мы совсем не подавили вывод трассировки. Однако, если вы выполните еще один вызов при перенаправлении stderr, вы увидите, что система ведения журналов работает, и мы можем изучать логи программы без необходимости личного присутствия во время появления ошибок:
|
$ python urlcaller.py http://thisurlprobablydoesntexist.com 2> my—logs.log —1 Connection Error |
Подведем итоги данного обучающего материала
Трассировка Python содержит замечательную информацию, которая может помочь вам понять, что идет не так с вашим кодом Python. Эти трассировки могут выглядеть немного запутанно, но как только вы поймете что к чему, и увидите, что они в себе несут, они могут быть предельно полезными. Изучив несколько трассировок, строку за строкой, вы получите лучшее представление о предоставляемой информации.
Понимание содержимого трассировки Python, когда вы запускаете ваш код может быть ключом к улучшению вашего кода. Это способ, которым Python пытается вам помочь.
Теперь, когда вы знаете как читать трассировку Python, вы можете выиграть от изучения ряда инструментов и техник для диагностики проблемы, о которой вам сообщает трассировка. Модуль traceback может быть полезным, если вам нужно узнать больше из выдачи трассировки.
- Текст является переводом статьи: Understanding the Python Traceback
- Изображение из шапки статьи принадлежит сайту © Real Python
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
It seems that there is confusion about how Python code can be executed and processed.
- On the one hand, there is the Python interpreter in the interactive mode. This is usually started with the command
python(without arguments) and then you have the possibility to execute Python code directly in an interactive Python specific shell. This distinguishes Python from other languages that need to be compiled first to execute code. Further information are available in the official Python tutorial. - On the other hand, Python can also be executed in such a way that not the interpreter with an interactive shell is started, but a file is read and processed. This is usually done with the command
pythontogether with the path to the Python file as argument, e.g.python test.py. See also the documentation about using Python.
With this knowledge the problems that have happened to you can now be explained and solved:
If you are simply starting the Python interpreter in interactive mode (without any further arguments), you don’t have access to the command line arguments any more, for example:
$ python3.8 # or whatever your command is, maybe only python or python3
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys; sys.argv
['']
As you can see, there isn’t really a usable information in argv. And that is your problem: The arguments aren’t successfully loaded into sys.argv. So an index error happened, because the arguments are simply missing:
$ python3.8
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.argv[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
The only difference to your example is that you have already provided the path to the script, because it’s File "C:/Users/MJavad/Desktop/test.py", line 3, in <module> instead of File "<stdin>", line 1, in <module>. So you have started the program via python test.py, but also without any further arguments which would be loaded into sys.argv in the program, see:
$ python3.8 test.py
Traceback (most recent call last):
File "test.py", line 3, in <module>
b = float(sys.argv[1])
IndexError: list index out of range
Your sys.argv now looks like this: ['test.py'], but still no index positions 1 and 2 available. So you have to invoke python also with additional arguments which will be passed into sys.argv:
$ python3.8 test.py 1 2
Traceback (most recent call last):
File "test.py", line 6, in <module>
d = math.sqrt(f)
ValueError: math domain error
And it worked! Ok, you have another exception, but it’s in line 6 and every line before was successfully processed, also the command line arguments. Now you can proceed to debug your program, i.e. start programming or trying other parameters than 1 and 2 etc.
So that’s the theory. Since you’re also using PyCharm and have the «Terminal», the «Run configuration» and a «Python Console» available, things get a bit more complicated:
- The «Terminal» should have a prompt available if you start one. This prompt shouldn’t be a prompt from the Python interpreter (normally prefixed by
>>>). It should be a terminal prompt (normally prefixed by an$at the end), where you can also start a python interpreter in interactive mode or start a python program as described above. This «Terminal» is a terminal emulator given you by PyCharm and can also do other things for you, not only starting python programs. See the PyCharm documentation for more information. - The «Python Console» is a similar Python interpreter you also can get if starting
pythonfrom the «Terminal». But then, you already started the interactive mode of the interpreter and there are no possibilities to pass command line arguments (maybe somewhere, but not as default). See the PyCharm documentation for more information. -
If you’re using an IDE like PyCharm, you should normally start the program as recommended by the IDE. In this case, you’re writing a file and start the file neither by running the «Terminal», nor going into an interactive Python shell. Instead of this, you have to configure the IDE «Run» as described in the PyCharm documentation or as you can see here:
This is just the GUI way of calling
python C:/Users/MJavad/Desktop/test.py 1 2directly inside PyCharm.
So I would recommend that you’re only starting your programs via option 3 (via «Run» configuration or «DEBUG» configuration). You only have to pay attention, running the right configuration (see if the path is the correct one and the parameters are right).
It is not normal to have a Python prompt (>>>) directly after starting a «Terminal», though. And inside interactive mode of Python’s interpreter, you simply cannot start a python script, because you’re already in a python interpreter, for example:
$ python3.8
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> python test.py 1 2
File "<stdin>", line 1
python test.py 1 2
^
SyntaxError: invalid syntax
I should also mention that you can pass arguments into python interactive mode, for example (the - stands for <stdin>):
$ python3.8 - hello world
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys; sys.argv
['-', 'hello', 'world']
>>>
Python известен своим простым синтаксисом. Однако, когда вы изучаете Python в первый раз или когда вы попали на Python с большим опытом работы на другом языке программирования, вы можете столкнуться с некоторыми вещами, которые Python не позволяет. Если вы когда-либо получали + SyntaxError + при попытке запустить код Python, то это руководство может вам помочь. В этом руководстве вы увидите общие примеры неправильного синтаксиса в Python и узнаете, как решить эту проблему.
Неверный синтаксис в Python
Когда вы запускаете ваш код Python, интерпретатор сначала анализирует его, чтобы преобразовать в байтовый код Python, который он затем выполнит. Интерпретатор найдет любой недопустимый синтаксис в Python на этом первом этапе выполнения программы, также известном как этап синтаксического анализа . Если интерпретатор не может успешно проанализировать ваш код Python, это означает, что вы использовали неверный синтаксис где-то в вашем коде. Переводчик попытается показать вам, где произошла эта ошибка.
Когда вы изучаете Python в первый раз, может быть неприятно получить + SyntaxError +. Python попытается помочь вам определить, где в вашем коде указан неверный синтаксис, но предоставляемый им traceback может немного сбить с толку. Иногда код, на который он указывает, вполне подходит.
*Примечание:* Если ваш код *синтаксически* правильный, то вы можете получить другие исключения, которые не являются `+ SyntaxError +`. Чтобы узнать больше о других исключениях Python и о том, как их обрабатывать, ознакомьтесь с https://realpython.com/python-exceptions/[Python Exceptions: Введение].
Вы не можете обрабатывать неправильный синтаксис в Python, как и другие исключения. Даже если вы попытаетесь обернуть блок + try + и + кроме + вокруг кода с неверным синтаксисом, вы все равно увидите, что интерпретатор вызовет + SyntaxError +.
+ SyntaxError + Исключение и трассировка
Когда интерпретатор обнаруживает неверный синтаксис в коде Python, он вызовет исключение + SyntaxError + и предоставит трассировку с некоторой полезной информацией, которая поможет вам отладить ошибку. Вот некоторый код, который содержит недопустимый синтаксис в Python:
1 # theofficefacts.py
2 ages = {
3 'pam': 24,
4 'jim': 24
5 'michael': 43
6 }
7 print(f'Michael is {ages["michael"]} years old.')
Вы можете увидеть недопустимый синтаксис в литерале словаря в строке 4. Во второй записи + 'jim' + пропущена запятая. Если вы попытаетесь запустить этот код как есть, вы получите следующую трассировку:
$ python theofficefacts.py
File "theofficefacts.py", line 5
'michael': 43
^
SyntaxError: invalid syntax
Обратите внимание, что сообщение трассировки обнаруживает ошибку в строке 5, а не в строке 4. Интерпретатор Python пытается указать, где находится неправильный синтаксис. Тем не менее, он может только указать, где он впервые заметил проблему. Когда вы получите трассировку + SyntaxError + и код, на который указывает трассировка, выглядит нормально, тогда вы захотите начать движение назад по коду, пока не сможете определить, что не так.
В приведенном выше примере нет проблемы с запятой, в зависимости от того, что следует после нее. Например, нет проблемы с отсутствующей запятой после + 'michael' + в строке 5. Но как только переводчик сталкивается с чем-то, что не имеет смысла, он может лишь указать вам на первое, что он обнаружил, что он не может понять.
*Примечание:* В этом руководстве предполагается, что вы знакомы с основами *tracebacks* в Python. Чтобы узнать больше о трассировке Python и о том, как их читать, ознакомьтесь с https://realpython.com/python-traceback/[Understanding Python Traceback].
Существует несколько элементов трассировки + SyntaxError +, которые могут помочь вам определить, где в вашем коде содержится неверный синтаксис:
-
Имя файла , где встречается неверный синтаксис
-
Номер строки и воспроизводимая строка кода, где возникла проблема
-
Знак (
+ ^ +) в строке ниже воспроизводимого кода, который показывает точку в коде, которая имеет проблему -
Сообщение об ошибке , которое следует за типом исключения
+ SyntaxError +, которое может предоставить информацию, которая поможет вам определить проблему
В приведенном выше примере имя файла было + theofficefacts.py +, номер строки был 5, а каретка указывала на закрывающую кавычку из словарного ключа + michael +. Трассировка + SyntaxError + может не указывать на реальную проблему, но она будет указывать на первое место, где интерпретатор не может понять синтаксис.
Есть два других исключения, которые вы можете увидеть в Python. Они эквивалентны + SyntaxError +, но имеют разные имена:
-
+ +IndentationError -
+ +TabError
Оба эти исключения наследуются от класса + SyntaxError +, но это особые случаи, когда речь идет об отступе. + IndentationError + возникает, когда уровни отступа вашего кода не совпадают. + TabError + возникает, когда ваш код использует и табуляцию, и пробелы в одном файле. Вы познакомитесь с этими исключениями более подробно в следующем разделе.
Общие проблемы с синтаксисом
Когда вы впервые сталкиваетесь с + SyntaxError +, полезно знать, почему возникла проблема и что вы можете сделать, чтобы исправить неверный синтаксис в вашем коде Python. В следующих разделах вы увидите некоторые из наиболее распространенных причин, по которым может быть вызвано «+ SyntaxError +», и способы их устранения.
Неправильное использование оператора присваивания (+ = +)
В Python есть несколько случаев, когда вы не можете назначать объекты. Некоторые примеры присваивают литералам и вызовам функций. В приведенном ниже блоке кода вы можете увидеть несколько примеров, которые пытаются это сделать, и получающиеся в результате трассировки + SyntaxError +:
>>>
>>> len('hello') = 5
File "<stdin>", line 1
SyntaxError: can't assign to function call
>>> 'foo' = 1
File "<stdin>", line 1
SyntaxError: can't assign to literal
>>> 1 = 'foo'
File "<stdin>", line 1
SyntaxError: can't assign to literal
Первый пример пытается присвоить значение + 5 + вызову + len () +. Сообщение + SyntaxError + очень полезно в этом случае. Он говорит вам, что вы не можете присвоить значение вызову функции.
Второй и третий примеры пытаются присвоить литералам строку и целое число. То же правило верно и для других литеральных значений. И снова сообщения трассировки указывают, что проблема возникает, когда вы пытаетесь присвоить значение литералу.
*Примечание:* В приведенных выше примерах отсутствует повторяющаяся строка кода и каретка (`+ ^ +`), указывающая на проблему в трассировке. Исключение и обратная трассировка, которые вы видите, будут другими, когда вы находитесь в REPL и пытаетесь выполнить этот код из файла. Если бы этот код был в файле, то вы бы получили повторяющуюся строку кода и указали на проблему, как вы видели в других случаях в этом руководстве.
Вероятно, ваше намерение не состоит в том, чтобы присвоить значение литералу или вызову функции. Например, это может произойти, если вы случайно пропустите дополнительный знак равенства (+ = +), что превратит назначение в сравнение. Сравнение, как вы можете видеть ниже, будет правильным:
>>>
>>> len('hello') == 5
True
В большинстве случаев, когда Python сообщает вам, что вы делаете присвоение чему-то, что не может быть назначено, вы сначала можете проверить, чтобы убедиться, что оператор не должен быть логическим выражением. Вы также можете столкнуться с этой проблемой, когда пытаетесь присвоить значение ключевому слову Python, о котором вы расскажете в следующем разделе.
Неправильное написание, отсутствие или неправильное использование ключевых слов Python
Ключевые слова Python — это набор защищенных слов , которые имеют особое значение в Python. Это слова, которые вы не можете использовать в качестве идентификаторов, переменных или имен функций в своем коде. Они являются частью языка и могут использоваться только в контексте, который допускает Python.
Существует три распространенных способа ошибочного использования ключевых слов:
-
Неправильное написание ключевое слово
-
Отсутствует ключевое слово
-
Неправильное использование ключевого слова
Если вы неправильно написали ключевое слово в своем коде Python, вы получите + SyntaxError +. Например, вот что происходит, если вы пишете ключевое слово + for + неправильно:
>>>
>>> fro i in range(10):
File "<stdin>", line 1
fro i in range(10):
^
SyntaxError: invalid syntax
Сообщение читается как + SyntaxError: неверный синтаксис +, но это не очень полезно. Трассировка указывает на первое место, где Python может обнаружить, что что-то не так. Чтобы исправить эту ошибку, убедитесь, что все ваши ключевые слова Python написаны правильно.
Другая распространенная проблема с ключевыми словами — это когда вы вообще их пропускаете:
>>>
>>> for i range(10):
File "<stdin>", line 1
for i range(10):
^
SyntaxError: invalid syntax
Еще раз, сообщение об исключении не очень полезно, но трассировка действительно пытается указать вам правильное направление. Если вы отойдете от каретки, то увидите, что ключевое слово + in + отсутствует в синтаксисе цикла + for +.
Вы также можете неправильно использовать защищенное ключевое слово Python. Помните, что ключевые слова разрешено использовать только в определенных ситуациях. Если вы используете их неправильно, у вас будет неправильный синтаксис в коде Python. Типичным примером этого является использование https://realpython.com/python-for-loop/#the-break-and-continue-statements [+ continue + или + break +] вне цикла. Это может легко произойти во время разработки, когда вы реализуете вещи и когда-то перемещаете логику за пределы цикла:
>>>
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
... print('jim found')
... break
...
File "<stdin>", line 3
SyntaxError: 'break' outside loop
>>> if 'jim' in names:
... print('jim found')
... continue
...
File "<stdin>", line 3
SyntaxError: 'continue' not properly in loop
Здесь Python отлично говорит, что именно не так. Сообщения " 'break' вне цикла " и " 'continue' не в цикле должным образом " помогут вам точно определить, что делать. Если бы этот код был в файле, то Python также имел бы курсор, указывающий прямо на неправильно использованное ключевое слово.
Другой пример — если вы пытаетесь назначить ключевое слово Python переменной или использовать ключевое слово для определения функции:
>>>
>>> pass = True
File "<stdin>", line 1
pass = True
^
SyntaxError: invalid syntax
>>> def pass():
File "<stdin>", line 1
def pass():
^
SyntaxError: invalid syntax
Когда вы пытаетесь присвоить значение + pass +, или когда вы пытаетесь определить новую функцию с именем + pass +, вы получите ` + SyntaxError + и снова увидеть сообщение + «неверный синтаксис» + `.
Может быть немного сложнее решить этот тип недопустимого синтаксиса в коде Python, потому что код выглядит хорошо снаружи. Если ваш код выглядит хорошо, но вы все еще получаете + SyntaxError +, то вы можете рассмотреть возможность проверки имени переменной или имени функции, которое вы хотите использовать, по списку ключевых слов для версии Python, которую вы используете.
Список защищенных ключевых слов менялся с каждой новой версией Python. Например, в Python 3.6 вы можете использовать + await + в качестве имени переменной или имени функции, но в Python 3.7 это слово было добавлено в список ключевых слов. Теперь, если вы попытаетесь использовать + await + в качестве имени переменной или функции, это вызовет + SyntaxError +, если ваш код для Python 3.7 или более поздней версии.
Другим примером этого является + print +, который отличается в Python 2 от Python 3:
| Version | print Type |
Takes A Value |
|---|---|---|
|
Python 2 |
keyword |
no |
|
Python 3 |
built-in function |
yes |
+ print + — это ключевое слово в Python 2, поэтому вы не можете присвоить ему значение. Однако в Python 3 это встроенная функция, которой можно присваивать значения.
Вы можете запустить следующий код, чтобы увидеть список ключевых слов в любой версии Python, которую вы используете:
import keyword
print(keyword.kwlist)
+ keyword + также предоставляет полезную + keyword.iskeyword () +. Если вам просто нужен быстрый способ проверить переменную + pass +, то вы можете использовать следующую однострочную строку:
>>>
>>> import keyword; keyword.iskeyword('pass')
True
Этот код быстро сообщит вам, является ли идентификатор, который вы пытаетесь использовать, ключевым словом или нет.
Отсутствующие скобки, скобки и цитаты
Часто причиной неправильного синтаксиса в коде Python являются пропущенные или несовпадающие закрывающие скобки, скобки или кавычки. Их может быть трудно обнаружить в очень длинных строках вложенных скобок или длинных многострочных блоках. Вы можете найти несоответствующие или пропущенные кавычки с помощью обратных трассировок Python:
>>>
>>> message = 'don't'
File "<stdin>", line 1
message = 'don't'
^
SyntaxError: invalid syntax
Здесь трассировка указывает на неверный код, где после закрывающей одинарной кавычки стоит + t '+. Чтобы это исправить, вы можете сделать одно из двух изменений:
-
Escape одиночная кавычка с обратной косой чертой (
+ 'don ' t '+) -
Окружить всю строку в двойных кавычках (
" не ")
Другая распространенная ошибка — забыть закрыть строку. Как для строк с двойными, так и с одинарными кавычками ситуация и обратная трассировка одинаковы:
>>>
>>> message = "This is an unclosed string
File "<stdin>", line 1
message = "This is an unclosed string
^
SyntaxError: EOL while scanning string literal
На этот раз каретка в трассировке указывает прямо на код проблемы. Сообщение + SyntaxError +, " EOL при сканировании строкового литерала ", немного более конкретно и полезно при определении проблемы. Это означает, что интерпретатор Python дошел до конца строки (EOL) до закрытия открытой строки. Чтобы это исправить, закройте строку с кавычкой, которая совпадает с той, которую вы использовали для ее запуска. В этом случае это будет двойная кавычка (`+» + `).
Кавычки, отсутствующие в инструкциях внутри f-string, также могут привести к неверному синтаксису в Python:
1 # theofficefacts.py
2 ages = {
3 'pam': 24,
4 'jim': 24,
5 'michael': 43
6 }
7 print(f'Michael is {ages["michael]} years old.')
Здесь, ссылка на словарь + ages + внутри напечатанной f-строки пропускает закрывающую двойную кавычку из ссылки на ключ. Итоговая трассировка выглядит следующим образом:
$ python theofficefacts.py
File "theofficefacts.py", line 7
print(f'Michael is {ages["michael]} years old.')
^
SyntaxError: f-string: unterminated string
Python идентифицирует проблему и сообщает, что она существует внутри f-строки. Сообщение " неопределенная строка " также указывает на проблему. Каретка в этом случае указывает только на начало струны.
Это может быть не так полезно, как когда каретка указывает на проблемную область струны, но она сужает область поиска. Где-то внутри этой f-строки есть неопределенная строка. Вы просто должны узнать где. Чтобы решить эту проблему, убедитесь, что присутствуют все внутренние кавычки и скобки f-строки.
Ситуация в основном отсутствует в скобках и скобках. Например, если вы исключите закрывающую квадратную скобку из списка, Python обнаружит это и укажет на это. Однако есть несколько вариантов этого. Первый — оставить закрывающую скобку вне списка:
# missing.py
def foo():
return [1, 2, 3
print(foo())
Когда вы запустите этот код, вам скажут, что есть проблема с вызовом + print () +:
$ python missing.py
File "missing.py", line 5
print(foo())
^
SyntaxError: invalid syntax
Здесь происходит то, что Python думает, что список содержит три элемента: + 1 +, + 2 + и +3 print (foo ()) +. Python использует whitespace для логической группировки вещей, и потому что нет запятой или скобки, отделяющей + 3 + от `+ print (foo ()) + `, Python объединяет их вместе как третий элемент списка.
Еще один вариант — добавить запятую после последнего элемента в списке, оставляя при этом закрывающую квадратную скобку:
# missing.py
def foo():
return [1, 2, 3,
print(foo())
Теперь вы получаете другую трассировку:
$ python missing.py
File "missing.py", line 6
^
SyntaxError: unexpected EOF while parsing
В предыдущем примере + 3 + и + print (foo ()) + были объединены в один элемент, но здесь вы видите запятую, разделяющую два. Теперь вызов + print (foo ()) + добавляется в качестве четвертого элемента списка, и Python достигает конца файла без закрывающей скобки. В трассировке говорится, что Python дошел до конца файла (EOF), но ожидал чего-то другого.
В этом примере Python ожидал закрывающую скобку (+] +), но повторяющаяся строка и каретка не очень помогают. Отсутствующие круглые скобки и скобки сложно определить Python. Иногда единственное, что вы можете сделать, это начать с каретки и двигаться назад, пока вы не сможете определить, чего не хватает или что нет.
Ошибочный синтаксис словаря
Вы видели ссылку: # syntaxerror-exception-and-traceback [ранее], чтобы вы могли получить + SyntaxError +, если не указывать запятую в словарном элементе. Другая форма недопустимого синтаксиса в словарях Python — это использование знака равенства (+ = +) для разделения ключей и значений вместо двоеточия:
>>>
>>> ages = {'pam'=24}
File "<stdin>", line 1
ages = {'pam'=24}
^
SyntaxError: invalid syntax
Еще раз, это сообщение об ошибке не очень полезно. Повторная линия и каретка, однако, очень полезны! Они указывают прямо на характер проблемы.
Этот тип проблемы распространен, если вы путаете синтаксис Python с синтаксисом других языков программирования. Вы также увидите это, если перепутаете определение словаря с вызовом + dict () +. Чтобы это исправить, вы можете заменить знак равенства двоеточием. Вы также можете переключиться на использование + dict () +:
>>>
>>> ages = dict(pam=24)
>>> ages
{'pam': 24}
Вы можете использовать + dict () + для определения словаря, если этот синтаксис более полезен.
Использование неправильного отступа
Существует два подкласса + SyntaxError +, которые конкретно занимаются проблемами отступов:
-
+ +IndentationError -
+ +TabError
В то время как другие языки программирования используют фигурные скобки для обозначения блоков кода, Python использует whitespace. Это означает, что Python ожидает, что пробелы в вашем коде будут вести себя предсказуемо. Он вызовет + IndentationError + , если в блоке кода есть строка с неправильным количеством пробелов:
1 # indentation.py
2 def foo():
3 for i in range(10):
4 print(i)
5 print('done')
6
7 foo()
Это может быть сложно увидеть, но в строке 5 есть только два пробела с отступом. Он должен соответствовать выражению цикла + for +, которое на 4 пробела больше. К счастью, Python может легко определить это и быстро расскажет вам, в чем проблема.
Здесь также есть некоторая двусмысленность. Является ли строка + print ('done') + after циклом + for + или inside блоком цикла + for +? Когда вы запустите приведенный выше код, вы увидите следующую ошибку:
$ python indentation.py
File "indentation.py", line 5
print('done')
^
IndentationError: unindent does not match any outer indentation level
Хотя трассировка выглядит во многом как трассировка + SyntaxError +, на самом деле это + IndentationError +. Сообщение об ошибке также очень полезно. Он говорит вам, что уровень отступа строки не соответствует ни одному другому уровню отступа. Другими словами, + print ('done') + это отступ с двумя пробелами, но Python не может найти любую другую строку кода, соответствующую этому уровню отступа. Вы можете быстро это исправить, убедившись, что код соответствует ожидаемому уровню отступа.
Другой тип + SyntaxError + — это + TabError + , который вы будете видеть всякий раз, когда есть строка, содержащая либо табуляцию, либо пробелы для отступа, в то время как остальная часть файла содержит другую. Это может скрыться, пока Python не покажет это вам!
Если размер вкладки равен ширине пробелов на каждом уровне отступа, то может показаться, что все строки находятся на одном уровне. Однако, если одна строка имеет отступ с использованием пробелов, а другая — с помощью табуляции, Python укажет на это как на проблему:
1 # indentation.py
2 def foo():
3 for i in range(10):
4 print(i)
5 print('done')
6
7 foo()
Здесь строка 5 имеет отступ вместо 4 пробелов. Этот блок кода может выглядеть идеально для вас, или он может выглядеть совершенно неправильно, в зависимости от настроек вашей системы.
Python, однако, сразу заметит проблему. Но прежде чем запускать код, чтобы увидеть, что Python скажет вам, что это неправильно, вам может быть полезно посмотреть пример того, как код выглядит при различных настройках ширины вкладки:
$ tabs 4 # Sets the shell tab width to 4 spaces
$ cat -n indentation.py
1 # indentation.py
2 def foo():
3 for i in range(10)
4 print(i)
5 print('done')
6
7 foo()
$ tabs 8 # Sets the shell tab width to 8 spaces (standard)
$ cat -n indentation.py
1 # indentation.py
2 def foo():
3 for i in range(10)
4 print(i)
5 print('done')
6
7 foo()
$ tabs 3 # Sets the shell tab width to 3 spaces
$ cat -n indentation.py
1 # indentation.py
2 def foo():
3 for i in range(10)
4 print(i)
5 print('done')
6
7 foo()
Обратите внимание на разницу в отображении между тремя примерами выше. Большая часть кода использует 4 пробела для каждого уровня отступа, но строка 5 использует одну вкладку во всех трех примерах. Ширина вкладки изменяется в зависимости от настройки tab width :
-
Если ширина вкладки равна 4 , то оператор
+ print +будет выглядеть так, как будто он находится вне цикла+ for +. Консоль выведет+ 'done' +в конце цикла. -
Если ширина табуляции равна 8 , что является стандартным для многих систем, то оператор
+ print +будет выглядеть так, как будто он находится внутри цикла+ for +. Консоль будет печатать+ 'done' +после каждого числа. -
Если ширина табуляции равна 3 , то оператор
+ print +выглядит неуместно. В этом случае строка 5 не соответствует ни одному уровню отступа.
Когда вы запустите код, вы получите следующую ошибку и трассировку:
$ python indentation.py
File "indentation.py", line 5
print('done')
^
TabError: inconsistent use of tabs and spaces in indentation
Обратите внимание на + TabError + вместо обычного + SyntaxError +. Python указывает на проблемную строку и дает вам полезное сообщение об ошибке. Это ясно говорит о том, что в одном и том же файле для отступа используется смесь вкладок и пробелов.
Решение этой проблемы состоит в том, чтобы все строки в одном и том же файле кода Python использовали либо табуляции, либо пробелы, но не обе. Для приведенных выше блоков кода исправление будет состоять в том, чтобы удалить вкладку и заменить ее на 4 пробела, которые будут печатать + 'done' + после завершения цикла + for +.
Определение и вызов функций
Вы можете столкнуться с неверным синтаксисом в Python, когда вы определяете или вызываете функции. Например, вы увидите + SyntaxError +, если будете использовать точку с запятой вместо двоеточия в конце определения функции:
>>>
>>> def fun();
File "<stdin>", line 1
def fun();
^
SyntaxError: invalid syntax
Трассировка здесь очень полезна, с помощью каретки, указывающей прямо на символ проблемы. Вы можете очистить этот неверный синтаксис в Python, отключив точку с запятой для двоеточия.
Кроме того, ключевые аргументы как в определениях функций, так и в вызовах функций должны быть в правильном порядке. Аргументы ключевых слов always идут после позиционных аргументов. Отказ от использования этого порядка приведет к + SyntaxError +:
>>>
>>> def fun(a, b):
... print(a, b)
...
>>> fun(a=1, 2)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
Здесь, еще раз, сообщение об ошибке очень полезно, чтобы рассказать вам точно, что не так со строкой.
Изменение версий Python
Иногда код, который прекрасно работает в одной версии Python, ломается в более новой версии. Это связано с официальными изменениями в синтаксисе языка. Наиболее известным примером этого является оператор + print +, который перешел от ключевого слова в Python 2 к встроенной функции в Python 3:
>>>
>>> # Valid Python 2 syntax that fails in Python 3
>>> print 'hello'
File "<stdin>", line 1
print 'hello'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello')?
Это один из примеров, где появляется сообщение об ошибке, сопровождающее + SyntaxError +! Он не только сообщает вам, что в вызове + print + отсутствует скобка, но также предоставляет правильный код, который поможет вам исправить оператор.
Другая проблема, с которой вы можете столкнуться, — это когда вы читаете или изучаете синтаксис, который является допустимым синтаксисом в более новой версии Python, но недопустим в той версии, в которую вы пишете. Примером этого является синтаксис f-string, которого нет в версиях Python до 3.6:
>>>
>>> # Any version of python before 3.6 including 2.7
>>> w ='world'
>>> print(f'hello, {w}')
File "<stdin>", line 1
print(f'hello, {w}')
^
SyntaxError: invalid syntax
В версиях Python до 3.6 интерпретатор ничего не знает о синтаксисе f-строки и просто предоставляет общее сообщение «» неверный синтаксис «`. Проблема, в данном случае, в том, что код looks прекрасно работает, но он был запущен с более старой версией Python. В случае сомнений перепроверьте, какая версия Python у вас установлена!
Синтаксис Python продолжает развиваться, и в Python 3.8 появилось несколько интересных новых функций:
-
Walrus оператор (выражения присваивания)
-
F-string синтаксис для отладки
*https://docs.python.org/3.8/whatsnew/3.8.html#positional-only-parameters[Positional-only arguments]
Если вы хотите опробовать некоторые из этих новых функций, то вам нужно убедиться, что вы работаете в среде Python 3.8. В противном случае вы получите + SyntaxError +.
Python 3.8 также предоставляет новый* + SyntaxWarning + *. Вы увидите это предупреждение в ситуациях, когда синтаксис допустим, но все еще выглядит подозрительно. Примером этого может быть отсутствие запятой между двумя кортежами в списке. Это будет действительный синтаксис в версиях Python до 3.8, но код вызовет + TypeError +, потому что кортеж не может быть вызван:
>>>
>>> [(1,2)(2,3)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
Этот + TypeError + означает, что вы не можете вызывать кортеж, подобный функции, что, как думает интерпретатор Python, вы делаете.
В Python 3.8 этот код все еще вызывает + TypeError +, но теперь вы также увидите + SyntaxWarning +, который указывает, как вы можете решить проблему:
>>>
>>> [(1,2)(2,3)]
<stdin>:1: SyntaxWarning: 'tuple' object is not callable; perhaps you missed a comma?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
Полезное сообщение, сопровождающее новый + SyntaxWarning +, даже дает подсказку (" возможно, вы пропустили запятую? "), Чтобы указать вам правильное направление!
Заключение
В этом руководстве вы увидели, какую информацию предоставляет обратная связь + SyntaxError +. Вы также видели много распространенных примеров неправильного синтаксиса в Python и каковы решения этих проблем. Это не только ускорит ваш рабочий процесс, но и сделает вас более полезным рецензентом кода!
Когда вы пишете код, попробуйте использовать IDE, который понимает синтаксис Python и предоставляет обратную связь. Если вы поместите многие из недопустимых примеров кода Python из этого руководства в хорошую IDE, то они должны выделить проблемные строки, прежде чем вы даже сможете выполнить свой код.
Получение + SyntaxError + во время изучения Python может быть неприятным, но теперь вы знаете, как понимать сообщения трассировки и с какими формами недопустимого синтаксиса в Python вы можете столкнуться. В следующий раз, когда вы получите + SyntaxError +, у вас будет больше возможностей быстро решить проблему!
Ошибки и исключения
В любой, особенно большой, программе могут возникать ошибки, приводящие к ее неработоспособности или к тому, что программа делает не то, что должна. Причин возникновения ошибок много.
Программист может сделать ошибку в употреблении самого языка программирования. Другими словами, выразиться так, как выражаться не положено. Например, начать имя переменной с цифры или забыть поставить двоеточие в заголовке сложной инструкции. Подобные ошибки называют синтаксическими, они нарушают синтаксис и пунктуацию языка. Интерпретатор Питона, встретив ошибочное выражение, не знает как его интерпретировать. Поэтому останавливает выполнение программы и выводит соответствующее сообщение, указав на место возникновения ошибки:
>>> 1a = 10 File "<stdin>", line 1 1a = 10 ^ SyntaxError: invalid syntax
В терминологии языка Python здесь возникло исключение, принадлежащее классу SyntaxError. Согласно документации Python синтаксические ошибки все-таки принято относить к ошибкам, а все остальные – к исключениям. В некоторых языках программирования не используется слово «исключение», а ошибки делят на синтаксические и семантические. Нарушение семантики обычно означает, что, хотя выражения написаны верно с точки зрения синтаксиса языка, программа не работает так, как от нее ожидалось. Для сравнения. Вы можете грамотным русским языком сказать несколько предложений, но по смыслу это будет белиберда, или вас поймут не так, как хотелось бы.
В Python не говорят о семантических ошибках, говорят об исключениях. Их множество. В этом уроке мы рассмотрим некоторые из них, в последующих встретимся с еще несколькими.
Если вы попытаетесь обратиться к переменной, которой не было присвоено значение, что в случае Python означает, что переменная вообще не была объявлена, она не существует, то возникнет исключение NameError.
>>> a = 0 >>> print(a + b) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'b' is not defined
Последнюю строку сообщения можно перевести как «Ошибка имени: имя ‘b’ не определено».
Если исключение возникает при выполнении кода из файла, то вместо «line 1» будет указана строка, в которой оно возникло, например, «line 24». Вместо «<stdin>» будет указано имя файла, например, «test.py». В данном же случае stdin обозначает стандартный поток ввода. По-умолчанию это поток ввода с клавиатуры. Строка 1 – потому что в интерактивном режиме каждое выражение интерпретируется отдельно, как обособленная программка. Если написать выражение, состоящее из нескольких строк, то линия возникновения ошибки может быть другой:
>>> a = 0 >>> if a == 0: ... print(a) ... print(a + b) ... 0 Traceback (most recent call last): File "<stdin>", line 3, in <module> NameError: name 'b' is not defined
Следующие два исключения, о которых следует упомянуть, и с которыми вы уже могли встретиться в предыдущих уроках, это ValueError и TypeError – ошибка значения и ошибка типа.
>>> int("Hi")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int()
with base 10: 'Hi'
>>> 8 + "3"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s)
for +: 'int' and 'str'
В примере строку «Hi» нельзя преобразовать к целому числу. Возникает исключение ValueError, потому что функция int() не может преобразовать такое значение.
Число 8 и строка «3» принадлежат разным типам, операнд сложения между которыми не поддерживается. При попытке их сложить возникает исключение TypeError.
Деление на ноль вызывает исключение ZeroDivisionError:
>>> 1/0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero
Обработка исключений. Оператор try-except
Когда ошибки в программе возникают в процессе написания кода или его тестирования, то код исправляется программистом так, чтобы ошибок не возникало. Однако нередко действия пользователя приводят к тому, что в программе возникает исключение. Например, программа ожидает ввод числа, но человек ввел букву. Попытка преобразовать ее к числу приведет к возбуждению исключения ValueError, и программа аварийно завершится.
На этот случай в языках программирования, в том числе Python, существует специальный оператор, позволяющий перехватывать возникающие исключения и обрабатывать их так, чтобы программа продолжала работать или корректно завершала свою работу.
В Питоне такой перехват выполняет оператор try-except. «Try» переводится как «попытаться», «except» – как исключение. Словами описать его работу можно так: «Попытаться сделать то-то и то-то, если при этом возникло исключение, то сделать вот это и это.» Его конструкция похожа на условный оператор с веткой else. Рассмотрим пример:
n = input("Введите целое число: ") try: n = int(n) print("Удачно") except: print("Что-то пошло не так")
Исключительная ситуация может возникнуть в третьей строчке кода, когда значение переменной n преобразуется к целому числу. Если это невозможно, то дальнейшее выполнение выражений в теле try прекращается. В данном случае выражение print("Удачно") выполнено не будет. При этом поток выполнения программы перейдет на ветку except и выполнит ее тело.
Если в теле try исключения не возникает, то тело ветки except не выполняется.
Вот пример вывода программы, когда пользователь вводит целое число:
Введите целое число: 100 Удачно
А здесь – когда вводит не то, что ожидалось:
Введите целое число: AA Что-то пошло не так
Есть одна проблема. Код выше обработает любое исключение. Однако в теле try могут возникать разные исключения, и у каждого из них должен быть свой обработчик. Поэтому более правильным является указание типа исключения после ключевого слова except.
try: n = input('Введите целое число: ') n = int(n) print("Все нормально. Вы ввели число", n) except ValueError: print("Вы ввели не целое число")
Теперь если сработает тело except мы точно знаем, из-за чего возникла ошибка. Но если в теле try возникнет еще какое-нибудь исключение, то оно не будет обработано. Для него надо написать отдельную ветку except. Рассмотрим программу:
try: a = float(input("Введите делимое: ")) b = float(input("Введите делитель: ")) c = a / b print("Частное: %.2f" % c) except ValueError: print("Нельзя вводить строки") except ZeroDivisionError: print("Нельзя делить на ноль")
При ее выполнении исключения могут возникнуть в трех строчках кода: где происходит преобразование введенных значений к вещественным числам и в месте, где происходит деление. В первом случае может возникнуть ValueError, во втором – ZeroDivisionError. Каждый тип исключения обрабатывается своей веткой except.
Несколько исключений можно сгруппировать в одну ветку и обработать совместно:
try: a = float(input("Введите делимое: ")) b = float(input("Введите делитель: ")) c = a / b print("Частное: %.2f" % c) except (ValueError, ZeroDivisionError): print("Нельзя вводить строки") print("или делить на ноль")
У оператора обработки исключений, кроме except, могут быть еще ветки finally и else (не обязательно обе сразу). Тело finally выполняется всегда, независимо от того, выполнялись ли блоки except в ответ на возникшие исключения или нет. Тело else сработает, если исключений в try не было, то есть не было переходов на блоки except.
try: n = input('Введите целое число: ') n = int(n) except ValueError: print("Неверный ввод") else: # когда в блоке try не возникло исключения print("Все нормально. Вы ввели число", n) finally: # выполняется в любом случае print("Конец программы")
Примечание. В данном коде используются комментарии. В языке Python перед ними ставится знак решетки #. Комментарии в программном коде пишутся исключительно для человека и игнорируются интерпретатором или компилятором.
Посмотрите, как выполняется программа в случае возникновения исключения и без этого:
pl@pl-desk:~$ python3 test.py Введите целое число: 4.3 Неверный ввод Конец программы pl@pl-desk:~$ python3 test.py Введите целое число: 4 Все нормально. Вы ввели число 4 Конец программы
В данном уроке изложены не все особенности обработки исключений. Так в более крупных программах, содержащих несколько уровней вложенности кода, функции, модули и классы, исключения могут обрабатываться не по месту их возникновения, а передаваться дальше по иерархии вызовов.
Также исключение может возникнуть в блоке except, else или finally, и тогда им нужен собственный обработчик. Модифицируем немного предыдущую программу и специально сгенерируем исключение в теле except:
try: n = input('Введите целое число: ') n = int(n) except ValueError: print("Неверный ввод") 3 / 0 except ZeroDivisionError: print("Деление на ноль") else: print("Все нормально. Вы ввели число", n) finally: print("Конец программы")
По началу может показаться, что все нормально. Исключение, генерируемое выражением 3 / 0 будет обработано веткой except ZeroDivisionError. Однако это не так. Эта ветка обрабатывает только исключения, возникающие в блоке try, к которому она сама относится. Вот вывод программы, если ввести не целое число:
Введите целое число: а Неверный ввод Конец программы Traceback (most recent call last): File "test.py", line 15, in <module> n = int(n) ValueError: invalid literal for int() with base 10: 'а' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "test.py", line 18, in <module> 3 / 0 ZeroDivisionError: division by zero
Мало того, что не было обработано деление на ноль, поскольку тело except ValueError неудачно завершилось, само исключение ValueError посчиталось необработанным. Решение проблемы может быть, например, таким:
… except ValueError: print("Неверный ввод") try: 3 / 0 except ZeroDivisionError: print("Деление на ноль") …
Здесь в тело except вложен свой внутренний обработчик исключений.
Практическая работа
Напишите программу, которая запрашивает ввод двух значений. Если хотя бы одно из них не является числом, то должна выполняться конкатенация, то есть соединение, строк. В остальных случаях введенные числа суммируются.
Примеры выполнения программы:
pl@pl-desk:~$ python3 test.py Первое значение: 4 Второе значение: 5 Результат: 9.0 pl@pl-desk:~$ python3 test.py Первое значение: a Второе значение: 9 Результат: a9
Примеры решения и дополнительные уроки в pdf-версии и android-приложении курса
Уведомления
- Начало
- » Python для новичков
- » SyntaxError: invalid syntax
#1 Фев. 15, 2010 23:57:11
SyntaxError: invalid syntax
привет всем,
изучаю python второй день, так что сразу прошу извинить за примитивность вопроса)
пытаюсь выполнить hello world, ввожу в командную строку:
$ python hello_world.py
и получаю сообщение об ошибке
File “<stdin>”, line 1
$ python hello_world.py
SyntaxError: invalid syntax
в учебнике об этом ничего не говорится, я понимаю, что вместо stdin должно быть названия файла со скриптом…
в общем, что можно с эитм сделать??
Офлайн
- Пожаловаться
#2 Фев. 16, 2010 10:15:17
SyntaxError: invalid syntax
а hello_world.py показать?
Офлайн
- Пожаловаться
#3 Фев. 16, 2010 12:03:50
SyntaxError: invalid syntax
slav0nic
а hello_world.py показать?
в смысле сам скрипт? вот он:
“”“
Problem: Get the computer to output a message
Target Users: Me
Target System: Windows
Interface: Command-line
Functional Requirements: Print out a message.
user must be able to input some text.
Testing: Simple run test — expecting a message to appear.
— expecting: message == input text
Maintainer: maintainer@website.com
”“”
# 1. Print out a friendly message
print(“Hello World!”)
# 2. Input some text
# 3. Print out the text we just entered
писал по учебнику “Python for Absolute beginners”, так что в скрипте много “нубовского” бреда… но если я правильно понимаю, то print должен быть выведен на экран. а между тем interpreter даже сам файл не видит
PS кстати сам скрипт содержится в Notepad++
Офлайн
- Пожаловаться
#4 Фев. 16, 2010 13:39:47
SyntaxError: invalid syntax
Какая версия питона? print стал функцией только в 3-м, если у тебя 2.х надо писать print “Hello World!”.
Офлайн
- Пожаловаться
#5 Фев. 16, 2010 13:42:04
SyntaxError: invalid syntax
Viper
Какая версия питона? print стал функцией только в 3-м, если у тебя 2.х надо писать print “Hello World!”.
у меня 3.1
Офлайн
- Пожаловаться
#6 Фев. 16, 2010 14:41:07
SyntaxError: invalid syntax
File “<stdin>”, line 1
Это значит, что ошибка в “потоке ввода” (то, что ты ручками в консоли пишешь) строке 1. Это наталкивает меня на дурные мысли, что “python hello_world.py” ты пишешь непосредственно в интерпретаторе питона, а не в системной консоли. Неужели я прав?
Офлайн
- Пожаловаться
#7 Фев. 16, 2010 14:52:46
SyntaxError: invalid syntax
dartNNN
File “<stdin>”, line 1
Это значит, что ошибка в “потоке ввода” (то, что ты ручками в консоли пишешь) строке 1. Это наталкивает меня на дурные мысли, что “python hello_world.py” ты пишешь непосредственно в интерпретаторе питона, а не в системной консоли. Неужели я прав?
извиняюсь, а что такое системная консоль?) консоль — это клавиатура, так? значит есть еще какой-то способ ввода — “системная консоль”?
я пока термины не очень освоил, но если под интерпретатором ты имел в виду черный такой экран с надписью python.exe на панели, то именно так оно и есть
Офлайн
- Пожаловаться
#8 Фев. 16, 2010 15:03:02
SyntaxError: invalid syntax
В данном контексте: “Системная консоль” = “командная строка”.
Черный экран с надписью Python.exe это интерпретатор запущенный в интерактивном режиме из консоли.
А вам надо просто: “Пуск”->“Выполнить…” и в появившемся окне написать “python <путь к вашему скрипту>”.
Офлайн
- Пожаловаться
#9 Фев. 16, 2010 15:32:22
SyntaxError: invalid syntax
regall
В данном контексте: “Системная консоль” = “командная строка”.
Черный экран с надписью Python.exe это интерпретатор запущенный в интерактивном режиме из консоли.
А вам надо просто: “Пуск”->“Выполнить…” и в появившемся окне написать “python <путь к вашему скрипту>”.
к сожалению, не получается. в лучшем случае, если я ввожу в “выполнить” точный путь к скрипту, он открывает notepad с этим скриптом, а мне вовсе не этого надо. а что касается самого слова python, то консоль его просто не понимает. да и вообще, зачем тогда сам интерпретатор нужен? в учебнике говорилось, что скрипт запускается при вводе $ python hello_world.py, так в чем же проблема?(
Офлайн
- Пожаловаться
#10 Фев. 16, 2010 15:35:50
SyntaxError: invalid syntax
win+R -> cmd -> cd c:scriptspython -> python script_name.py
давай спроси меня что значит -> 
Офлайн
- Пожаловаться
- Начало
- » Python для новичков
- » SyntaxError: invalid syntax



