imp
— Доступ до внутрішніх елементів import¶
Вихідний код: Lib/imp.py
Цей модуль надає інтерфейс для механізмів, що використовуються для реалізації оператора import
. Він визначає такі константи та функції:
- imp.get_magic()¶
Повертає магічне значення рядка, яке використовується для розпізнавання файлів зі скомпільованим кодом (
.pyc
файли). (Це значення може відрізнятися для кожної версії Python.)Застаріло починаючи з версії 3.4: Натомість використовуйте
importlib.util.MAGIC_NUMBER
.
- imp.get_suffixes()¶
Повертає список 3-елементних кортежів, кожен з яких описує певний тип модуля. Кожна трійка має вигляд
(суфікс, режим, тип)
, де суфікс — це рядок, який додається до назви модуля, щоб сформувати назву файлу для пошуку, mode — це рядок режиму, який передається до вбудована функціяopen()
для відкриття файлу (це може бути'r'
для текстових файлів або'rb'
для бінарних файлів), а type — це тип файлу, який має одне зі значеньPY_SOURCE
,PY_COMPILED
абоC_EXTENSION
, описаних нижче.Застаріло починаючи з версії 3.3: Натомість використовуйте константи, визначені в
importlib.machinery
.
- imp.find_module(name[, path])¶
Спробуйте знайти ім’я модуля. Якщо path пропущено або
None
, пошук здійснюється за списком імен каталогів, наданимsys.path
, але спочатку виконується пошук у кількох спеціальних місцях: функція намагається знайти вбудований модуль за допомогою дане ім’я (C_BUILTIN
), потім заморожений модуль (PY_FROZEN
), а в деяких системах також переглядаються деякі інші місця (у Windows шукається в реєстрі, який може вказувати на певний файл).В іншому випадку path має бути списком імен каталогів; у кожному каталозі шукаються файли з будь-якими суфіксами, які повертає
get_suffixes()
вище. Недійсні імена в списку мовчки ігноруються (але всі елементи списку мають бути рядками).Якщо пошук пройшов успішно, повертається значення 3-елементного кортежу
(файл, шлях, опис)
:file — це відкритий file object, розташований на початку, pathname — це шлях до знайденого файлу, а description — це 3-елементний кортеж, який міститься у списку, який повертає
get_suffixes()
, що описує вид знайденого модуля.Якщо модуль вбудований або заморожений, тоді file і pathname мають значення
None
, а кортеж description містить порожні рядки для свого суфікса та режиму; тип модуля вказано у дужках вище. Якщо пошук невдалий, виникаєImportError
. Інші винятки вказують на проблеми з аргументами або середовищем.Якщо модуль є пакетом, file має значення
None
, pathname — це шлях до пакета, а останнім елементом у кортежі description єPKG_DIRECTORY
.Ця функція не обробляє ієрархічні імена модулів (імена, що містять крапки). Щоб знайти P.M, тобто підмодуль M пакета P, використовуйте
find_module()
іload_module()
, щоб знайти та завантажити пакет P, а потім використовуйтеfind_module()
з аргументом path, встановленим наP.__path__
. Якщо P має назву з крапками, застосовуйте цей рецепт рекурсивно.Застаріло починаючи з версії 3.3: Використовуйте
importlib.util.find_spec()
замість цього, якщо не потрібна сумісність з Python 3.3, у такому випадку використовуйтеimportlib.find_loader()
. Для прикладу використання першого випадку дивіться розділ Приклади документаціїimportlib
.
- imp.load_module(name, file, pathname, description)¶
Завантажте модуль, який раніше було знайдено за допомогою
find_module()
(або за допомогою іншого здійсненого пошуку, що дає сумісні результати). Ця функція робить більше, ніж імпорт модуля: якщо модуль уже було імпортовано, він перезавантажить модуль! Аргумент name вказує на повну назву модуля (включно з назвою пакета, якщо це підмодуль пакета). Аргумент file — це відкритий файл, а pathname — ім’я відповідного файлу; вони можуть бутиNone
і''
відповідно, якщо модуль є пакетом або не завантажується з файлу. Аргумент description є кортежем, який повертаєget_suffixes()
, описуючи тип модуля, який потрібно завантажити.Якщо завантаження пройшло успішно, повертається значення об’єкта модуля; інакше виникає виняток (зазвичай
ImportError
).Важливо: абонент, що викликає, відповідає за закриття аргументу file, якщо він не був
None
, навіть якщо виникає виняток. Найкраще це зробити за допомогою оператораtry
…finally
.Застаріло починаючи з версії 3.3: Якщо раніше використовувався в поєднанні з
imp.find_module()
, розгляньте можливість використанняimportlib.import_module()
, інакше використовуйте завантажувач, повернутий заміною, яку ви вибрали дляimp.find_module()
. Якщо ви викликалиimp.load_module()
та пов’язані функції безпосередньо з аргументами шляху до файлу, тоді використовуйте комбінаціюimportlib.util.spec_from_file_location()
таimportlib.util.module_from_spec()
. Перегляньте розділ Приклади документаціїimportlib
для детальної інформації про різні підходи.
- imp.new_module(name)¶
Повертає новий порожній об’єкт модуля під назвою name. Цей об’єкт не вставляється в
sys.modules
.Застаріло починаючи з версії 3.4: Натомість використовуйте
importlib.util.module_from_spec()
.
- imp.reload(module)¶
Перезавантажте раніше імпортований модуль. Аргумент має бути об’єктом модуля, тому він має бути успішно імпортований раніше. Це корисно, якщо ви відредагували вихідний файл модуля за допомогою зовнішнього редактора і хочете випробувати нову версію, не виходячи з інтерпретатора Python. Поверненим значенням є об’єкт модуля (те саме, що аргумент module).
Коли виконується
reload(module)
:Код модулів Python перекомпілюється, а код рівня модуля повторно виконується, визначаючи новий набір об’єктів, які прив’язані до імен у словнику модуля. Функція
init
модулів розширення не викликається вдруге.Як і у випадку з усіма іншими об’єктами в Python, старі об’єкти відновлюються лише після того, як їх кількість посилань зменшується до нуля.
Імена в просторі імен модуля оновлюються, щоб вказувати на будь-які нові або змінені об’єкти.
Інші посилання на старі об’єкти (наприклад, імена, зовнішні по відношенню до модуля) не повертаються до нових об’єктів і повинні бути оновлені в кожному просторі імен, де вони зустрічаються, якщо це потрібно.
Існує ряд інших застережень:
Коли модуль перезавантажується, його словник (що містить глобальні змінні модуля) зберігається. Перевизначення імен замінить старі визначення, тому це, як правило, не проблема. Якщо нова версія модуля не визначає назву, яка була визначена старою версією, старе визначення залишається. Цю функцію можна використати на користь модуля, якщо він підтримує глобальну таблицю або кеш об’єктів — за допомогою оператора
try
він може перевіряти наявність таблиці та пропускати її ініціалізацію, якщо потрібно:try: cache except NameError: cache = {}
Перезавантажувати вбудовані або динамічно завантажувані модулі, за винятком
sys
,__main__
іbuiltins
, є законним, хоча загалом не дуже корисно. Однак у багатьох випадках модулі розширення не призначені для ініціалізації більше ніж один раз і можуть виходити з ладу довільним чином під час перезавантаження.Якщо модуль імпортує об’єкти з іншого модуля за допомогою
from
…import
…, викликreload()
для іншого модуля не перевизначає об’єкти, імпортовані з нього — один спосіб обійти це — повторно виконати операторfrom
, інший — використати замість ньогоimport
і кваліфіковані імена (module.*name*).Якщо модуль створює екземпляри класу, перезавантаження модуля, який визначає клас, не впливає на визначення методів екземплярів — вони продовжують використовувати старе визначення класу. Те саме стосується похідних класів.
Змінено в версії 3.3: Покладається на те, що
__name__
і__loader__
визначені в модулі, який перезавантажується, а не просто__name__
.Застаріло починаючи з версії 3.4: Натомість використовуйте
importlib.reload()
.
Наступні функції є зручними для обробки шляхів PEP 3147 скомпільованих файлів.
Нове в версії 3.2.
- imp.cache_from_source(path, debug_override=None)¶
Поверніть шлях PEP 3147 до скомпільованого файлу, пов’язаного з вихідним шляхом. Наприклад, якщо path є
/foo/bar/baz.py
, значення, що повертається, буде/foo/bar/__pycache__/baz.cpython-32.pyc
для Python 3.2. Рядокcpython-32
походить від поточного магічного тегу (див.get_tag()
; якщоsys.implementation.cache_tag
не визначено, тоді буде викликанаNotImplementedError
). ПередаючиTrue
абоFalse
для debug_override, ви можете змінити системне значення для__debug__
, що призведе до оптимізації байт-коду.шлях не повинен існувати.
Змінено в версії 3.3: Якщо
sys.implementation.cache_tag
має значенняNone
, тоді виникаєNotImplementedError
.Застаріло починаючи з версії 3.4: Натомість використовуйте
importlib.util.cache_from_source()
.Змінено в версії 3.5: Параметр debug_override більше не створює файл
.pyo
.
- imp.source_from_cache(path)¶
Враховуючи шлях до імені файлу PEP 3147, поверніть пов’язаний шлях до файлу вихідного коду. Наприклад, якщо шлях є
/foo/bar/__pycache__/baz.cpython-32.pyc
, повернутий шлях буде/foo/bar/baz.py
. path не обов’язково існує, однак, якщо він не відповідає формату PEP 3147, виникаєValueError
. Якщоsys.implementation.cache_tag
не визначено, виникаєNotImplementedError
.Змінено в версії 3.3: Викликати
NotImplementedError
, колиsys.implementation.cache_tag
не визначено.Застаріло починаючи з версії 3.4: Натомість використовуйте
importlib.util.source_from_cache()
.
- imp.get_tag()¶
Повертає рядок магічного тегу PEP 3147, що відповідає цій версії магічного числа Python, яке повертає
get_magic()
.Застаріло починаючи з версії 3.4: Використовуйте
sys.implementation.cache_tag
безпосередньо, починаючи з Python 3.3.
Наступні функції допомагають взаємодіяти з внутрішнім механізмом блокування системи імпорту. Семантика блокування імпорту є деталлю реалізації, яка може відрізнятися від випуску до випуску. Однак Python гарантує, що циклічний імпорт працює без будь-яких взаємоблокувань.
- imp.lock_held()¶
Повертає
True
, якщо наразі утримується глобальне блокування імпорту, інакшеFalse
. На платформах без потоків завжди повертайтеFalse
.На платформах із потоками потік, який виконує імпорт, спочатку утримує глобальне блокування імпорту, а потім встановлює блокування кожного модуля для решти імпорту. Це блокує інші потоки від імпорту того самого модуля до завершення оригінального імпорту, не даючи іншим потокам побачити незавершені об’єкти модуля, створені вихідним потоком. Виняток зроблено для циклічного імпорту, який за своєю конструкцією в певний момент має відкрити незавершений об’єкт модуля.
Змінено в версії 3.3: Схема блокування здебільшого змінена на помодульні блокування. Глобальне блокування імпорту зберігається для деяких критичних завдань, таких як ініціалізація блокувань для кожного модуля.
Застаріло починаючи з версії 3.4.
- imp.acquire_lock()¶
Отримати глобальне блокування імпорту інтерпретатора для поточного потоку. Це блокування має використовуватися гаками імпорту, щоб забезпечити безпеку потоків під час імпорту модулів.
Як тільки потік отримав блокування імпорту, той самий потік може отримати його знову без блокування; потік повинен звільнити його один раз за кожен раз, коли він його отримав.
На платформах без потоків ця функція нічого не робить.
Змінено в версії 3.3: Схема блокування здебільшого змінена на помодульні блокування. Глобальне блокування імпорту зберігається для деяких критичних завдань, таких як ініціалізація блокувань для кожного модуля.
Застаріло починаючи з версії 3.4.
- imp.release_lock()¶
Звільніть глобальне блокування імпорту інтерпретатора. На платформах без потоків ця функція нічого не робить.
Змінено в версії 3.3: Схема блокування здебільшого змінена на помодульні блокування. Глобальне блокування імпорту зберігається для деяких критичних завдань, таких як ініціалізація блокувань для кожного модуля.
Застаріло починаючи з версії 3.4.
Наступні константи з цілими значеннями, визначені в цьому модулі, використовуються для позначення результату пошуку find_module()
.
- imp.PY_SOURCE¶
Модуль знайдено як вихідний файл.
Застаріло починаючи з версії 3.3.
- imp.PY_COMPILED¶
Модуль знайдено як скомпільований об’єктний файл коду.
Застаріло починаючи з версії 3.3.
- imp.C_EXTENSION¶
Модуль було знайдено як спільну бібліотеку, що динамічно завантажується.
Застаріло починаючи з версії 3.3.
- imp.PKG_DIRECTORY¶
Модуль знайдено як каталог пакунків.
Застаріло починаючи з версії 3.3.
- imp.C_BUILTIN¶
Модуль знайдено як вбудований модуль.
Застаріло починаючи з версії 3.3.
- imp.PY_FROZEN¶
Модуль було знайдено як заморожений.
Застаріло починаючи з версії 3.3.
- class imp.NullImporter(path_string)¶
Тип
NullImporter
— це PEP 302 хук імпорту, який обробляє рядки шляху, не пов’язані з каталогом, не знаходячи жодного модуля. Виклик цього типу з наявним каталогом або порожнім рядком викликаєImportError
. В іншому випадку повертається екземплярNullImporter
.Примірники мають лише один метод:
- find_module(fullname[, path])¶
Цей метод завжди повертає
None
, вказуючи, що запитуваний модуль не вдалося знайти.
Змінено в версії 3.3:
None
вставляється вsys.path_importer_cache
замість екземпляраNullImporter
.Застаріло починаючи з версії 3.4: Натомість вставте
None
уsys.path_importer_cache
.
Приклади¶
Наступна функція емулює те, що було стандартним оператором імпорту до Python 1.4 (без ієрархічних імен модулів). (Ця реалізація не працюватиме в цій версії, оскільки find_module()
було розширено, а load_module()
додано у 1.4.)
import imp
import sys
def __import__(name, globals=None, locals=None, fromlist=None):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass
# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.
fp, pathname, description = imp.find_module(name)
try:
return imp.load_module(name, fp, pathname, description)
finally:
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()