Как импортировать модуль с указанием полного пути? - PullRequest
933 голосов
/ 16 сентября 2008

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

Ответы [ 26 ]

10 голосов
/ 16 сентября 2008
def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except:
        raise ImportError

import_file('/home/somebody/somemodule.py')
8 голосов
/ 16 сентября 2008

Полагаю, вы можете использовать imp.find_module() и imp.load_module() для загрузки указанного модуля. Вам нужно будет разделить имя модуля по пути, то есть, если вы хотите загрузить /home/mypath/mymodule.py, вам нужно сделать:

imp.find_module('mymodule', '/home/mypath/')

... но это должно сделать работу.

3 голосов
/ 02 октября 2015

Чтобы импортировать модуль из заданного имени файла, вы можете временно расширить путь и восстановить системный путь в блоке finally ссылка:

filename = "directory/module.py"

directory, module_name = os.path.split(filename)
module_name = os.path.splitext(module_name)[0]

path = list(sys.path)
sys.path.insert(0, directory)
try:
    module = __import__(module_name)
finally:
    sys.path[:] = path # restore
3 голосов
/ 02 июня 2015

Я не говорю, что это лучше, но для полноты картины я хотел предложить функцию exec, доступную как в Python 2, так и в 3. exec позволяет выполнять произвольный код либо в глобальной области, либо во внутренней области, представленной в виде словаря.

Например, если у вас есть модуль, хранящийся в "/path/to/module "с функцией foo(), вы можете запустить его, выполнив следующее:

module = dict()
with open("/path/to/module") as f:
    exec(f.read(), module)
module['foo']()

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

И если для вас важен доступ через атрибуты, а не ключи, вы можете разработать собственный класс dict для глобалов, который обеспечивает такой доступ, например ::

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)
3 голосов
/ 13 сентября 2014

Вы можете использовать модуль pkgutil (в частности, метод walk_packages), чтобы получить список пакетов в текущем каталоге. Оттуда тривиально использовать механизм importlib для импорта необходимых модулей:

import pkgutil
import importlib

packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
    mod = importlib.import_module(name)
    # do whatever you want with module now, it's been imported!
3 голосов
/ 04 января 2012

Это должно работать

path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
    basename = os.path.basename(infile)
    basename_without_extension = basename[:-3]

    # http://docs.python.org/library/imp.html?highlight=imp#module-imp
    imp.load_source(basename_without_extension, infile)
3 голосов
/ 06 декабря 2018

Создать модуль python test.py

import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3

Создание модуля Python test_check.py

from test import Client1
from test import Client2
from test import test3

Мы можем импортировать импортированный модуль из модуля.

3 голосов
/ 12 апреля 2015

Эта область Python 3.4 кажется чрезвычайно сложной для понимания! Однако с небольшим количеством взлома, используя код от Криса Кэллоуэя как начало, мне удалось заставить кое-что работать. Вот основная функция.

def import_module_from_file(full_path_to_module):
    """
    Import a module given the full path/filename of the .py file

    Python 3.4

    """

    module = None

    try:

        # Get module name and path from full path
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)

        # Get module "spec" from filename
        spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)

        module = spec.loader.load_module()

    except Exception as ec:
        # Simple error printing
        # Insert "sophisticated" stuff here
        print(ec)

    finally:
        return module

Похоже, что используются устаревшие модули из Python 3.4. Я не притворяюсь, что понимаю почему, но, похоже, это работает изнутри программы. Я обнаружил, что решение Криса работает в командной строке, но не внутри программы.

2 голосов
/ 16 сентября 2008

Импорт модулей пакета во время выполнения (рецепт Python)

http://code.activestate.com/recipes/223972/

###################
##                #
## classloader.py #
##                #
###################

import sys, types

def _get_mod(modulePath):
    try:
        aMod = sys.modules[modulePath]
        if not isinstance(aMod, types.ModuleType):
            raise KeyError
    except KeyError:
        # The last [''] is very important!
        aMod = __import__(modulePath, globals(), locals(), [''])
        sys.modules[modulePath] = aMod
    return aMod

def _get_func(fullFuncName):
    """Retrieve a function object from a full dotted-package name."""

    # Parse out the path, module, and function
    lastDot = fullFuncName.rfind(u".")
    funcName = fullFuncName[lastDot + 1:]
    modPath = fullFuncName[:lastDot]

    aMod = _get_mod(modPath)
    aFunc = getattr(aMod, funcName)

    # Assert that the function is a *callable* attribute.
    assert callable(aFunc), u"%s is not callable." % fullFuncName

    # Return a reference to the function itself,
    # not the results of the function.
    return aFunc

def _get_class(fullClassName, parentClass=None):
    """Load a module and retrieve a class (NOT an instance).

    If the parentClass is supplied, className must be of parentClass
    or a subclass of parentClass (or None is returned).
    """
    aClass = _get_func(fullClassName)

    # Assert that the class is a subclass of parentClass.
    if parentClass is not None:
        if not issubclass(aClass, parentClass):
            raise TypeError(u"%s is not a subclass of %s" %
                            (fullClassName, parentClass))

    # Return a reference to the class itself, not an instantiated object.
    return aClass


######################
##       Usage      ##
######################

class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass

def storage_object(aFullClassName, allOptions={}):
    aStoreClass = _get_class(aFullClassName, StorageManager)
    return aStoreClass(allOptions)
2 голосов
/ 08 июня 2011

Я сделал пакет, который использует imp для вас. Я называю это import_file, и вот как оно используется:

>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')

Вы можете получить его по адресу:

http://pypi.python.org/pypi/import_file

или

http://code.google.com/p/import-file/

...