Вопрос-Ответ

How can I import a module dynamically given the full path?

Как я могу динамически импортировать модуль с указанием полного пути?

Как мне загрузить модуль Python с указанием его полного пути?

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


Смотрите также: Как импортировать модуль с указанием его имени в виде строки?

Переведено автоматически
Ответ 1

Давайте определим модуль MyClass in module.name по адресу /path/to/file.py. Ниже показано, как мы импортируем MyClass из этого модуля

Для Python 3.5+ используйте (документы):

import importlib.util
import sys
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
sys.modules["module.name"] = foo
spec.loader.exec_module(foo)
foo.MyClass()

Для Python 3.3 и 3.4 используйте:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(Хотя это устарело в Python 3.4.)

Для Python 2 используйте:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

Существуют эквивалентные удобные функции для скомпилированных файлов Python и DLL.

Смотрите также http://bugs.python.org/issue21436.

Ответ 2

Преимущество добавления пути к sys.path (по сравнению с использованием imp) заключается в том, что это упрощает процесс импорта более одного модуля из одного пакета. Например:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch
Ответ 3

Чтобы импортировать ваш модуль, вам нужно добавить его каталог в переменную среды, временно или постоянно.

Временно

import sys
sys.path.append("/path/to/my/modules/")
import my_module

Постоянно

Добавляем следующую строку в ваш .bashrc (или альтернативный) файл в Linux и выполняем execute source ~/.bashrc (или альтернативный) в терминале:

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

Предоставлено / Источник: saarrrr, еще один вопрос Stack Exchange

Ответ 4

Если ваш модуль верхнего уровня не является файлом, а упакован в виде каталога с __init__.py , то принятое решение почти работает, но не совсем. В Python 3.5+ необходим следующий код (обратите внимание на добавленную строку, начинающуюся с 'sys.modules'):

MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)

Без этой строки, когда выполняется exec_module, он пытается привязать относительный импорт на вашем верхнем уровне __init__.py к имени модуля верхнего уровня - в данном случае "mymodule". Но "mymodule" еще не загружен, поэтому вы получите сообщение об ошибке "SystemError: родительский модуль "mymodule" не загружен, не удается выполнить относительный импорт". Итак, вам нужно привязать имя перед его загрузкой. Причиной этого является фундаментальный инвариант относительной системы импорта: "Неизменным является то, что если у вас есть sys.modules['spam'] и sys.modules['spam.foo'] (как было бы после вышеупомянутого импорта), последний должен отображаться как атрибут foo первого" как обсуждалось здесь .

python