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

Разберите практический результат импорта: какое имя появится в глобальной области видимости после выполнения кода и почему обращение к sax завершится ошибкой?

import xml.sax

print(xml.__name__)
try:
    print(sax.__name__)
except NameError:
    print("NameError")
Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

В глобальной области видимости появится имя xml, но не отдельное имя sax. Поэтому программа выведет xml, затем NameError. Конструкция import xml.sax импортирует подмодуль, но связывает в текущем пространстве имён верхнеуровневое имя xml.

Исторический контекст

Иерархическая система модулей и пакетов нужна для организации большого кода и предотвращения конфликтов имён. Полное имя xml.sax сохраняет информацию о принадлежности подмодуля пакету и не загрязняет текущую область видимости множеством коротких имён.

Такой подход также позволяет явно выбирать стиль использования: обращаться к объекту как xml.sax или отдельно импортировать нужное имя через from xml import sax.

Постановка проблемы

Ошибка возникает, когда разработчик ожидает, что каждая часть пути импорта автоматически станет отдельной переменной. Это приводит к неверным обращениям вроде sax.parse(...) после import xml.sax.

Неправильное предположение особенно опасно в коде с несколькими пакетами, где короткое имя может быть не определено или конфликтовать с другим объектом.

Подробное решение

При выполнении import xml.sax Python находит пакет xml, загружает подмодуль xml.sax и обеспечивает доступ к нему через атрибут sax объекта xml. В текущей области видимости при этом создаётся привязка имени xml.

Имя sax само по себе не создаётся, поэтому его чтение вызывает NameError. Вывод будет таким:

xml NameError

Если нужно получить отдельное имя sax, следует написать:

from xml import sax print(sax.__name__)

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

Важно отличать форму импорта от факта загрузки модуля: Python может сохранить загруженный модуль в sys.modules, но наличие записи там не означает автоматического появления одноимённой переменной в каждой области видимости.

Ситуация из практики

В проекте используется import xml.sax, после чего разработчик пишет sax.make_parser(). Вариант с заменой на import xml.sax as sax даёт короткое имя и явно создаёт нужную привязку, но скрывает пакетный префикс.

Вариант from xml import sax также работает и выглядит компактнее, однако при наличии нескольких модулей с именем sax источник становится менее очевидным. Для небольшого локального участка разумен алиас import xml.sax as sax; в публичном или крупном модуле часто предпочтительнее сохранять квалифицированное обращение xml.sax, чтобы происхождение имени было видно.

Что кандидаты часто упускают

  1. Дополнительный вопрос: создаст ли import xml.sax атрибут sax у объекта xml?

Ответ: да, после успешного импорта подмодуль обычно доступен как xml.sax. Пакет xml выступает объектом модуля, а sax — его атрибутом, соответствующим загруженному подмодулю. Это не означает появления переменной sax в текущем пространстве имён.

  1. Дополнительный вопрос: чем в части создаваемых имён отличается import xml.sax as parser?

Ответ: такая форма связывает в текущей области видимости имя parser с импортированным подмодулем xml.sax. Имена xml и sax как локальные привязки этой инструкцией не требуются. Алиас полезен для сокращения длинного пути или устранения конфликта имён.

  1. Дополнительный вопрос: что изменится при выполнении from xml import sax после import xml.sax?

Ответ: в текущей области видимости появится отдельная привязка sax, указывающая на тот же объект модуля xml.sax. Повторная загрузка исходного кода модуля обычно не требуется, поскольку импорт использует кэш sys.modules. Однако локальная привязка sax и атрибут xml.sax остаются разными именами, указывающими на один объект.