Ошибка NameError: name '...' is not defined в Python означает, что программа встретила имя, которое сейчас не определено или недоступно.
Имя в кавычках — уже подсказка: проверь его написание, найди место создания, посмотри на порядок выполнения и область видимости. Оборачивать строку в try/except обычно не нужно — надо восстановить отсутствующую связь между именем и значением.
Коротко: как исправить NameError?
- Прочитай последнюю строку traceback и посмотри на имя в кавычках.
- Сверь написание буква в букву, включая регистр:
total,TotalиTOTAL— разные имена. - Убедись, что присваивание,
defилиimportвыполнились до проблемной строки. - Проверь область видимости: локальное имя из функции снаружи не доступно.
- Если это модуль или псевдоним вроде
mathилиpd, проверь импорт в том же файле или запущенной ячейке. - Если хотел вывести текст или обратиться к строковому ключу словаря, добавь кавычки.
Кот-наставник— Я кот-наставник — твой проводник по Python на платформе SkillPy. У
NameErrorполезная привычка: он почти всегда называет виновника прямо в кавычках. Не чини весь файл наугад — сначала найди именно это имя.
Что означает NameError: name is not defined?
NameError — исключение, которое Python вызывает, когда не находит локальное или глобальное имя. Это может быть имя переменной, функции, класса, импортированного модуля или другого объекта.
Фраза
name 'total' is not definedпереводится как «имяtotalне определено». Речь не обязательно о переменной: Python одинаково ищет все имена без точки, напримерtotal,calculateилиmath.
message = "Заказ готов"
print(mesage)Ошибка выполнения — main.py, строка 2
NameError: name 'mesage' is not defined
Python дошёл до print(mesage) и попытался найти имя mesage. Такого имени нет, зато есть похожее message, поэтому интерпретатор даже предложил исправление. Подсказка Did you mean появляется не всегда, но стандартное сообщение name is not defined указывает неизвестное имя между кавычками.
Присваивание message = "Заказ готов" не кладёт значение в «ячейку с фиксированным названием». Оно связывает имя message со строкой. Опечатка создаёт запрос к другому имени, с которым ничего не связано. Именно эта причина лежит в основе всех вариантов NameError.
Точное определение исключения можно сверить с официальной документацией Python 3.12.
Почему возникает NameError в Python?
| Что видно в коде | Что произошло | Что проверить |
|---|---|---|
| mesage вместо message | Опечатка или другой регистр | Каждый символ имени |
| Имя используется выше присваивания или def | Нужная строка ещё не выполнилась | Порядок выполнения |
| Имя создано внутри функции | Снаружи оно не видно | Параметры и return |
| math, pd или plt не найдены | Нет импорта или не тот псевдоним | Строку import в этом файле |
| print(Привет) или data[name] | Текст принят за имя | Кавычки вокруг строки |
| Имя создаётся только внутри if | Нужная ветка не сработала | Значение по умолчанию |
1. Опечатка или другой регистр
Самая частая причина — имя создано, но ниже написано иначе. Python чувствителен к регистру, поэтому price, Price и PRICE — три разных имени. Сравни имя из последней строки traceback с присваиванием или def, а не полагайся на беглый взгляд.
Особенно коварны похожие буквы из разных алфавитов. Латинская c и кириллическая с, латинская x и кириллическая х выглядят почти одинаково, но для Python это разные символы. Если имя кажется правильным, удали его целиком и набери заново в английской раскладке.
2. Имя используется до создания
print(total)
total = 1550Ошибка выполнения — main.py, строка 1
NameError: name 'total' is not defined
Python выполняет код верхнего уровня сверху вниз. Когда первая строка пытается прочитать total, присваивание ниже ещё не выполнялось. Переставь строки: сначала свяжи имя со значением, потом используй его.
total = 1550
print(total)1550
С функциями действует тот же принцип. Инструкция def создаёт имя функции только тогда, когда выполнение дошло до неё. Поэтому вызов greet() выше def greet(): на верхнем уровне даст NameError, а вызов ниже определения сработает.
Есть важная граница: имя внутри тела функции ищется в момент вызова, а не в момент чтения строки def. Поэтому функция может обращаться к глобальному имени, записанному ниже неё, если это имя успело появиться до вызова. Механическое правило «всё всегда должно стоять выше функции» неверно — важен реальный порядок выполнения.
3. Переменная осталась внутри функции
def calculate_total():
total = 1200 + 350
return total
calculate_total()
print(total)Ошибка выполнения — main.py, строка 6
NameError: name 'total' is not defined
Имя total локально для calculate_total(). Оно доступно внутри функции, но не появляется снаружи только потому, что функция была вызвана. return отдаёт значение, однако его ещё нужно сохранить во внешнее имя.
def calculate_total():
total = 1200 + 350
return total
order_total = calculate_total()
print(order_total)1550
Так данные проходят границу функции явно: значение выходит через return, а снаружи получает имя order_total. Переносить локальную переменную в глобальную область обычно не нужно. Параметры, return и области видимости подробно разобраны в статье «Функции в Python: от def до lambda».
4. Забыт import или перепутан псевдоним
print(math.sqrt(81))Ошибка выполнения — main.py, строка 1
NameError: name 'math' is not defined
Модуль math входит в стандартную библиотеку, но его имя не появляется автоматически. Импорт тоже связывает имя с объектом. Добавь его до использования:
import math
print(math.sqrt(81))9.0
Форма импорта определяет доступное имя. После import math работает math.sqrt(81). После from math import sqrt работает sqrt(81), но имя math не создаётся. После import pandas as pd доступен псевдоним pd, а не pandas.
Импорт в соседнем файле не делает имя доступным во всём проекте. Каждый модуль имеет собственное глобальное пространство имён, поэтому импорт нужен в том файле, где имя используется.
5. Строка или ключ словаря написаны без кавычек
В выражении print(Привет) слово Привет не считается текстом. Без кавычек Python воспринимает его как имя и пытается найти значение. Если это обычная строка, исправление простое: print("Привет").
Та же ловушка встречается у словарей:
``python
profile = {"name": "Анна"}
print(profile[name]) # Python ищет переменную name
print(profile["name"]) # Python использует строковый ключ
Если переменная name не создана, первая строка даст NameError. После добавления кавычек Python начнёт искать ключ в словаре. Если такого ключа нет, это будет уже другая ошибка — KeyError`.
6. Переменная создаётся не во всех ветках if
is_member = False
if is_member:
discount = 10
print(discount)Ошибка выполнения — main.py, строка 6
NameError: name 'discount' is not defined
Присваивание написано выше print, но этого недостаточно: ветка if не выполнилась, поэтому имя discount так и не появилось. Задай безопасное значение до условия, а внутри ветки меняй его при необходимости.
discount = 0
is_member = False
if is_member:
discount = 10
print(discount)0
Проверь не только if, но и циклы, try и ранний return: любой путь до строки использования должен либо создать имя, либо завершить выполнение раньше. Как устроены ветки и значения по умолчанию, смотри в статье «if, elif и else в Python — условия с примерами».
Почему переменная определена, но Python её не видит?
Если присваивание точно есть, вопрос нужно уточнить: где оно выполнилось и видно ли имя из текущей строки. Python ищет имя от ближайшей области к более широкой. Этот порядок часто называют правилом LEGB.
| Область | Где находится имя | Пример |
|---|---|---|
| Local | В текущей функции | Параметр или локальная переменная |
| Enclosing | Во внешней функции | Имя из функции-обёртки |
| Global | На уровне текущего файла | Импорт или присваивание вне функций |
| Built-in | Среди встроенных имён Python | print, len, range |
Если совпадения нет ни в одной доступной области, возникает NameError. Цикл for и условие if не создают отдельную область видимости, а функция создаёт. Поэтому переменная из тела if может быть видна ниже — если ветка действительно сработала, — а локальная переменная функции снаружи не видна никогда.
В Jupyter Notebook, интерактивной консоли и окне Python в IDE есть ещё состояние сессии. После перезапуска ядра старые имена исчезают. Если ячейки запускались не по порядку, код на экране может выглядеть правильным, но нужное присваивание в текущей сессии не выполнялось. Перезапусти ядро и выполни все ячейки сверху вниз; в обычном проекте запускай весь файл, а не только выделенную строку.
NameError, UnboundLocalError и AttributeError — в чём разница?
| Ошибка | Что не нашёл Python | Пример |
|---|---|---|
| NameError | Доступное имя целиком | print(total) |
| UnboundLocalError | Значение уже распознанной локальной переменной | total = total + 1 внутри функции |
| AttributeError | Атрибут справа от точки | user.emial вместо user.email |
| ModuleNotFoundError | Модуль во время import | import missing_package |
UnboundLocalError — подкласс NameError, но у него отдельный поисковый интент и другая причина. Python уже решил, что имя локальное, однако код читает его до присваивания значения. Разбор этой механики и исправление через параметры и return есть в статье «UnboundLocalError в Python: причина и как исправить».
AttributeError относится только к части после точки. Если user существует, но user.email нет, имя user Python нашёл — значит, это не NameError. А если ошибка возникает прямо в строке import, ищи причину среди ImportError и ModuleNotFoundError, а не маскируй её обработчиком NameError.
Почему try/except не исправляет NameError?
Для обычной программы NameError почти всегда означает дефект самого кода. Исправь имя, порядок выполнения, передачу результата или импорт. Перехватывать NameError уместно только в редком коде, который намеренно работает с динамическими пространствами имён. Для данных снаружи программы обрабатывают ожидаемые ошибки ввода, файлов или сети, а не отсутствие собственных имён.
Это и есть граница применимости: try/except нужен для предусмотренной ситуации во время работы программы, но не для сокрытия опечатки разработчика.
Где та же логика сломает код снова?
- После
del totalсвязь с именем удаляется. Следующее обращение кtotalснова дастNameError. - Имя, созданное только на одной итерации цикла или в успешной ветке
try, может отсутствовать на другом пути выполнения. - Псевдонимы библиотек работают только после соответствующего импорта:
pdтребуетimport pandas as pd, аplt— свой импорт. - После перезапуска Jupyter или интерактивной консоли нужно заново выполнить ячейки с присваиваниями, функциями и импортами.
- Попытка изменить внешнюю переменную внутри функции часто приводит уже к
UnboundLocalError, а не к обычномуNameError.
Короткие ответы про NameError
Как переводится NameError: name is not defined?
«Ошибка имени: имя не определено». Python встретил имя переменной, функции, класса или модуля, которого нет в доступной области видимости.
Почему Python пишет is not defined, хотя переменная есть в коде?
Присваивание могло ещё не выполниться, находиться внутри другой функции, остаться в незапущенной ячейке или попасть в ветку if, которая не сработала. Ещё проверь регистр и похожие кириллические буквы.
Как исправить NameError: name 'pd' is not defined?
Выполни import pandas as pd в том же файле или в текущей сессии до обращения к pd. Если сам импорт падает, это уже проблема установки или импорта пакета, а не NameError.
Что значит NameError: name 'self' is not defined?
self — обычное имя параметра метода, а не специальная глобальная команда. Если возник именно NameError, код обращается к self там, где параметра с таким именем нет: например, вне метода или внутри функции с другой сигнатурой.
Можно ли исправить NameError через global?
Само по себе — нет. global указывает, что присваивание внутри функции относится к имени на уровне модуля, но не создаёт отсутствующее значение. Обычно надёжнее передать значение параметром и вернуть результат через return.
Главное про NameError:
- Имя в кавычках — отправная точка
Python прямо указывает имя, которого не нашёл. Начинай диагностику с него, а не со всего файла.
- Проверок всего четыре
Сверь написание и регистр, порядок выполнения, область видимости и импорт. Для текста и строковых ключей отдельно проверь кавычки.
- Имя должно появляться на каждом пути
Присваивание внутри
if, цикла илиtryне поможет, если выполнение до него не дошло. - Похожие ошибки имеют другие причины
UnboundLocalErrorотносится к локальной переменной без значения, аAttributeError— к атрибуту после точки. - Обработчик не заменяет исправление
try/except NameErrorможет скрыть дефект, но не восстановит неверное имя, порядок строк или область видимости.
Кот-наставник— Последняя строка traceback не ругается, а оставляет адрес: вот имя, которого мне не хватило. Проверь, где оно должно было появиться и почему эта строка его не видит, — так
NameErrorпревращается из тупика в короткую диагностику.
Научи traceback помогать, а не пугать!
На SkillPy ты пишешь код сам, а AI-наставник разбирает именно твою ошибку: показывает неизвестное имя, объясняет область видимости и помогает найти причину. Первые задачи доступны бесплатно.
