imp — Доступ до внутрішніх елементів import

Вихідний код: Lib/imp.py

Застаріло з версії 3.4, буде видалено у версії 3.12: Модуль imp застарів на користь importlib.


Цей модуль надає інтерфейс для механізмів, що використовуються для реалізації оператора 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, навіть якщо виникає виняток. Найкраще це зробити за допомогою оператора tryfinally.

Застаріло починаючи з версії 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, є законним, хоча загалом не дуже корисно. Однак у багатьох випадках модулі розширення не призначені для ініціалізації більше ніж один раз і можуть виходити з ладу довільним чином під час перезавантаження.

Якщо модуль імпортує об’єкти з іншого модуля за допомогою fromimport …, виклик 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()