Архив метки: import

Python: from import для импорта пакетов

Использование инструкции import могут оказаться несколько неудобным для импортирования  пакетов,  потому  что  в  этом  случае  далее  в  программе  вам придется часто вводить полные пути для обращения к именам. В примере из предыдущего раздела, например, приходилось каждый раз вводить полный путь от dir1, когда необходимо было обратиться к переменой z. Если попытаться  непосредственно  обратиться  к  dir2 или  mod,  будет  получено  сообщение  об ошибке:
>>> dir2.mod
NameError: name ‘dir2’ is not defined
>>> mod.z
NameError: name ‘mod’ is not defined


Поэтому  для  импортирования  пакетов  часто  более  удобно  использовать  инструкцию from, чтобы избежать необходимости ввода полного имени при каждом  обращении  к  нему.  Еще  более  важно  следующее:  если  вы  когда-нибудь произведете реструктуризацию дерева каталогов, то в случае использования инструкции from достаточно будет обновить путь только в самой этой инструкции, тогда как в случае использования инструкции import придется обновлять все обращения к именам в изменившемся пакете. Расширение import as, обсуждаемое в следующей главе, поможет вам определить сокращенные синонимы
для полных путей:
% python
>>> from dir1.dir2 import mod  # Описание пути находится только в этом месте
dir1 init
dir2 init
in mod.py
>>> mod.z                      # Указывать полный путь не требуется
3
>>> from dir1.dir2.mod import z
>>> z
3
>>> import dir1.dir2.mod as mod    # Использование короткого синонима
>>> mod.z
3

Автор: Няшный Человек
Дата публикации: 2016-04-07T21:54:00.000+03:00

Повторная загрузка модулей

Как мы уже видели, программный код модуля по умолчанию запускается всего один раз за все время работы программы. Чтобы принудительно повторно загрузить модуль и запустить программный код в нем, необходимо явно вызвать встроенную функцию reload. В этом разделе мы исследуем, как использовать возможность повторной загрузки модулей, чтобы сделать систему более динамичной. В двух словах:
•  При  вызове  операции  импортирования  (с  помощью  инструкций  import и from) программный код модуля загружается и выполняется, только когда модуль импортируется в первый раз за время работы программы.
•  При последующих попытках импортировать модуль будет использоваться объект уже загруженного модуля. Повторная загрузка и запуск программного кода в этом случае не происходит.


•  Функция reload принудительно выполняет повторную загрузку уже загруженного модуля и запускает его программный код. Инструкции присваивания, выполняемые при повторном запуске, будут изменять существующий объект модуля.
Для чего вся эта суета вокруг повторной загрузки модулей? Функция reload позволяет изменять части программы, не останавливая всю программу. Благодаря функции reload эффект от изменений в программном коде можно наблюдать сразу же после внесения этих изменений. Повторная загрузка модулей поможет не во всех ситуациях, но она позволит существенно сократить цикл разработки. Например, представьте себе программу, предназначенную для работы с базами данных, которая должна при запуске соединиться с сервером, – так как изменения или настройки могут проверяться немедленно после повторной
загрузки, вам достаточно соединиться с базой данных всего один раз за весь сеанс отладки. Таким же способом можно обновлять программный код долго работающих серверов, которые нельзя останавливать.
Язык Python относится к языкам интерпретирующего типа (более или менее), поэтому в нем отсутствуют этапы компиляции/компоновки, необходимые, чтобы запустить программу, например, на языке C модули загружаются динамически уже запущенной программой. Возможность повторной загрузки обеспечивает  повышение  производительности  труда,  позволяя  вам  изменять  части работающей программы без ее остановки. Обратите внимание, что в настоящее время функция reload может обслуживать только модули, написанные на языке Python, – скомпилированные модули расширений, написанные на таких языках, как C, тоже могут динамически загружаться во время работы программы, но их нельзя загрузить повторно.

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

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

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

Файл 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

Пространства имен модулей

Модули будут, вероятно, более понятны, если представлять их, как простые пакеты имен, – то есть место, где определяются переменные, которые должны быть доступны остальной системе.
С технической точки зрения каждому модулю соответствует отдельный файл, и интерпретатор создает объект модуля, содержащий все имена, которым присвоены какие-либо значения в файле модуля. Проще говоря, модули – это всего лишь пространства имен (места, где создаются имена), и имена, находящиеся в модуле, называются его атрибутами.В данной тематике мы разберем как работает этот механизм.

Файлы создают пространства имен
Итак, как же файлы трансформируются в пространства имен? Суть в том, что каждое имя, которому присваивается некоторое значение на верхнем уровне файла модуля (то есть не вложенное в функции или в классы), превращается в атрибут этого модуля.
Например, операция присваивания, такая как X = 1, на верхнем уровне модуля M.py превращает имя X в атрибут модуля M, обратиться к которому из-за пределов модуля можно как M.X. Кроме того, имя X становится глобальной переменной для программного кода внутри M.py, но нам необходимо более формально объяснить понятия загрузки модуля и областей видимости, чтобы понять, почему:
•  Инструкции  модуля  выполняются  во  время  первой  попытки  импорта. Когда модуль импортируется в первый раз, интерпретатор Python создает пустой объект модуля и выполняет инструкции в модуле одну за другой, от начала файла до конца.
•  Операции присваивания, выполняемые на верхнем уровне, создают атрибуты  модуля.  Во  время  импортирования  инструкции  присваивания,  выполняемые на верхнем уровне файла и не вложенные в инструкции def или class (например, =, def), создают атрибуты объекта модуля – при присваивании имена сохраняются в пространстве имен модуля.
•  Доступ  к  пространствам  имен  модулей  можно  получить  через  атрибут __dict__  или  dir(M).  Пространства  имен  модулей,  создаваемые  операцией импортирования, представляют собой словари – доступ к ним можно получить через встроенный атрибут __dict__, ассоциированный с модулем, и с помощью функции dir. Функция dir – это примерный эквивалент отсортированного списка ключей атрибута __dict__, но она включает унаследованные имена классов, может возвращать не полный список и часто изменяется от версии к версии.
 Модуль  –  это  единая  область  видимости  (локальная  является  глобальной). Как мы видели в главе 17, имена на верхнем уровне модуля подчиняются тем же правилам обращения/присваивания, что и имена в функциях, только в этом случае локальная область видимости совпадает с глобальной (точнее, они следуют тому же правилу LEGB поиска в областях видимости, с которым мы познакомились в главе 17, только без уровней поиска L и E). 
Но в модулях область видимости модуля после загрузки модуля превращается в атрибут-словарь объекта модуля. В отличие от функций (где локальное пространство имен существует только во время выполнения функции), область видимости файла модуля превращается в область видимости атрибутов объекта модуля и никуда не исчезает после выполнения операции импортирования.
Ниже эти понятия демонстрируются в программном коде. Предположим, мы 
создаем в текстовом редакторе следующий файл модуля с именем module2.py:
Print(‘starting to load…’)
import sys
name = 42
 
def func(): pass
 
class klass: pass
 
print(‘done loading.’)

Когда  модуль  будет  импортироваться  в  первый  раз  (или  будет  запущен  как программа), интерпретатор выполнит инструкции модуля от начала до конца. В ходе операции импортирования одни инструкции создают имена в пространстве имен модуля, а другие выполняют определенную работу. Например, две инструкции print в этом файле выполняются во время импортирования:
>>> imp
ort module2
starting to load…
done loading.
Но  как  только  модуль  будет  загружен,  его  область  видимости  превратится в пространство имен атрибутов объекта модуля, который возвращает инструкция import. После этого можно обращаться к атрибутам в этом пространстве 
имен, дополняя их именем вмещающего модуля:
>>> module2.sys
 
>>> module2.name
42
 
>>> module2.func
>
 
>>> module2.klass
Здесь именам sys, name, func и klass были присвоены значения во время выполнения инструкций модуля, поэтому они стали атрибутами после завершения операции импортирования. О классах мы будем говорить в шестой части книги, но обратите внимание на атрибут sys – инструкции  import действительно присваивают объекты модулей именам, а любая операция присваивания на 
верхнем уровне файла создает атрибут модуля.
Внутри интерпретатора пространства имен хранятся в  виде объектов словарей. Это самые обычные объекты словарей с обычными методами. Обратиться к словарю пространства имен модуля можно через атрибут __dict__ модуля (не забудьте обернуть вызов этого метода вызовом функции list – в Python 3.0 он возвращает объект представления!):
>>> list(module2.__dict__.keys())
[‘name’, ‘__builtins__’, ‘__file__’, ‘__package__’, ‘sys’, ‘klass’, ‘func’,
‘__name__’, ‘__doc__’]
Имена, которые были определены в файле модуля, становятся ключами внутри словаря, таким образом, большинство имен здесь отражают операции 
присваивания на верхнем уровне в файле. Однако интерпретатор Python  добавляет в пространство имен модуля еще несколько имен, например __file__ содержит имя файла, из которого был загружен модуль, а  __name__ – это имя, под которым модуль известен импортерам (без расширения .py и без пути к каталогу).

Автор: Няшный Человек
Дата публикации: 2014-08-16T04:04:00.000+03:00

Когда использовать import

И так, в предыдущем посте, было рассказано о минусах инструкции from и о том, что использование import более надежней и практичней. Поэтому речь пойдет о использовании import.


Единственное,  когда  необходимо  вместо  инструкции  from  использовать  инструкцию import, – когда требуется использовать одно и то же имя, присутствующее в двух разных модулях. Например, когда два файла по-разному определяют одно и то же имя:
# M.py

def func():
    …выполнить что-то одно…

# N.py

def func():
    …выполнить что-то другое…
и необходимо использовать обе версии имени в программе. В этом случае инструкцию from использовать нельзя, потому что в результате вы получите единственное имя в вашей области видимости:
# O.py

from M import func
from N import func     # Перезапишет имя, импортированное из модуля M
func()                 # Будет вызвана N.func
Зато  можно  использовать  инструкцию  import,  потому  что  включение  имени

вмещающего модуля сделает имена уникальными:

# O.py
 
import M, N    # Получить модуль целиком, а не отдельные имена
M.func()       # Теперь можно вызывать обе функции
N.func()       # Наличие имени модуля делает их уникальными
Этот случай достаточно необычен, поэтому вы вряд ли часто будете сталкиваться с ним на практике. Но если такая ситуация все-таки возникнет, инструкция import позволит вам избежать конфликта имен.
Фух, за день две статьи, спасибо за подписи, надеюсь количество увеличиться и увеличится количество статей. Ставим + , приглашаем друзей и комментируйте записи.

Автор: Няшный Человек
Дата публикации: 2014-05-25T11:42:00.002+03:00

Минусы инструкции from

Здравствуйте читатели. Ну что, вот вам еще очередная порция текста по программированию используя Python )
На этот раз речь пойдет о минусах использовании инструкции from.




 — У инструкции from менее явное отображение переменной (имя name несет меньше информации, чем module.name), поэтому некоторые пользователи Python  рекомендуют  использовать  инструкцию  import  вместо from. Но это иногда можно опровергнуть, так как такой использование from происходит довольно таки часто и без страшных последствий.

 — Инструкция from способна повреждать пространства имен, по крайней мере, в принципе – если использовать ее для импортирования переменных, когда существуют одноименные переменные в имеющейся области видимости, то эти переменные просто будут перезаписаны. Эта проблема отсутствует при использовании инструкции import, потому что доступ к содержимому импортируемого модуля возможен только через его имя (имя module.attr не конфликтует с именем attr в текущей области видимости). 
Пока вы понимаете и контролируете все, что может происходить при использовании инструкции from, во всем этом нет большой проблемы, особенно если импортируемые имена указываются явно (например, from module import x, y, z).

С другой стороны, инструкция from скрывает в себе более серьезные проблемы, когда используется в комбинации с функцией reload, так как импортированные имена могут ссылаться на предыдущие версии объектов. Кроме того, инструкция в форме from module import * действительно может повреждать пространства имен и затрудняет понимание имен, особенно когда она применяется более чем к одному файлу, – в этом случае нет никакого способа определить, какому модулю принадлежит то или иное имя, разве только выполнить поиск по файлам с исходными текстами. В действительности форма from * вставляет одно пространство имен в другое, что сводит на нет преимущества, которые несет возможность разделения пространств имен.

Пожалуй, лучший совет, который можн