Архив метки: Области видимости

Вложенные пространства имен

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

Файл mod3.py определяет единственное глобальное имя и атрибут операцией присваивания:
X = 3
Файл mod2.py определяет свою переменную X, затем импортирует модуль mod3 и спользует квалификацию имени, чтобы получить доступ к атрибуту импортированного модуля:
X = 2
import mod3

print(X, end=’ ‘)      # Моя глобальная переменная X
print mod3.X           # Глобальная переменная X из модуля mod3
Файл mod1.py также определяет свою собственную переменную X, затем импортирует модуль mod2 и получает значения атрибутов обоих модулей:
X = 1
import mod2

print(X, end=’ ‘)          # Моя глобальная переменная X
print(mod2.X, end=’ ‘)     # Переменная X из модуля mod2
print(mod2.mod3.X          # Переменная X из модуля mod3
В  действительности,  когда  mod1  импортирует  mod2,  он  создает  двухуровневое вложение пространств имен. Используя полный путь к имени mod2.mod3.X, он может погрузиться в модуль mod3, который вложен в импортированный модуль mod2. Суть в том, что модуль mod1 может обращаться к переменным X во всех трех файлах и, следовательно, имеет доступ ко всем трем глобальным областям видимости:
% python mod1.py
2 3
1 2 3
Однако обратное утверждение неверно: модуль mod3 не имеет доступа к именам в mod2, а модуль mod2 не имеет доступа к именам в mod1. Возможно, этот пример будет проще понять, если отвлечься от пространств имен и областей видимости и сосредоточиться на объектах, задействованных в примере. mod2 внутри модуля mod1 – это всего лишь имя, которое ссылается на объект с атрибутами, некоторые из которых могут ссылаться на другие объекты с атрибутами (инструкция import выполняет операцию присваивания). Для таких путей, как
mod2.mod3.X, интерпретатор Python выполняет вычисления слева направо, извлекая атрибуты из объектов.

Обратите внимание: в mod1 можно вставить инструкцию import mod2 и затем использовать обращение mod2.mod3.X, но нельзя записать import mod2.mod3 – такой синтаксис используется для операции импортирования пакетов (каталогов), которая будет описана в следующей главе. При импортировании пакетов также создаются вложенные пространства имен, но в этом случае инструкция import воспринимает свой аргумент как дерево каталогов, а не как цепочку модулей.

Автор: Няшный Человек
Дата публикации: 2015-11-11T22:57:00.000+02:00

Импортирование и области видимости

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


Например,  рассмотрим  два  следующих  простых  модуля.  Первый, в файле  moda.py,
определяет переменную X, которая является глобальной только для программного кода в этом файле, и функцию, изменяющую глобальную переменную
в этом файле:
X = 88         # Переменная X: глобальная только для этого файла
def f():
    global X   # Изменяет переменную X в этом файле
    X = 99     # Имена в других модулях недоступны
Второй модуль, modb.py, определяет свою собственную глобальную перемен-
ную X, а также импортирует и вызывает функцию из первого модуля:
X = 11         # Переменная X: глобальная только для этого файла 

import moda    # Получает доступ к именам в модуле moda
moda.f()       # Изменяет переменную moda.X, но не X в этом файле
print X, moda.X

При запуске этого модуля функция moda.f изменит переменную X в модуле moda, а не в modb. Глобальной областью видимости для функции moda.f всегда является файл, вмещающий ее, независимо от того, из какого модуля она была вызвана:
% python modb.py
11 99
Другими словами, операция импортирования никогда не изменяет область видимости для программного кода в импортируемом файле – из импортируемого файла нельзя получить доступ к именам в импортирующем файле. Если быть более точным:

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

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

Автор: Няшный Человек
Дата публикации: 2015-10-04T08:43:00.000+03:00