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

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

Ответы [ 26 ]

2 голосов
/ 18 ноября 2014

В Linux работает добавление символической ссылки в каталог, в котором находится ваш скрипт на python.

то есть:

ln -s /absolute/path/to/module/module.py /absolute/path/to/script/module.py

python создаст /absolute/path/to/script/module.pyc и обновит его, если вы измените содержимое /absolute/path/to/module/module.py

затем включите следующее в mypythonscript.py

from module import *
1 голос
/ 24 мая 2018

Простое решение с использованием importlib вместо пакета imp (протестировано для Python 2.7, хотя должно работать и для Python 3):

import importlib

dirname, basename = os.path.split(pyfilepath) # pyfilepath: '/my/path/mymodule.py'
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # '/my/path/mymodule.py' --> 'mymodule'
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")

Теперь вы можете напрямую использовать пространство имен импортируемого модуля, например:

a = module.myvar
b = module.myfunc(a)

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

1 голос
/ 26 января 2018

довольно простой способ: предположим, что вы хотите импортировать файл с относительным путем ../../MyLibs/pyfunc.py


libPath = '../../MyLibs'
import sys
if not libPath in sys.path: sys.path.append(libPath)
import pyfunc as pf

Но если вы сделаете это без охраны, вы, наконец, сможете пройти очень длинный путь

0 голосов
/ 08 сентября 2018

Этот ответ является дополнением к ответу Себастьяна Риттау, отвечающему на комментарий: «а что, если у вас нет имени модуля?» Это быстрый и грязный способ получения вероятного имени модуля python по имени файла - он просто идет вверх по дереву, пока не найдет каталог без файла __init__.py, а затем превратит его обратно в имя файла. Для Python 3.4+ (использует pathlib), что имеет смысл, поскольку пользователи Py2 могут использовать «imp» или другие способы выполнения относительного импорта:

import pathlib

def likely_python_module(filename):
    '''
    Given a filename or Path, return the "likely" python module name.  That is, iterate
    the parent directories until it doesn't contain an __init__.py file.

    :rtype: str
    '''
    p = pathlib.Path(filename).resolve()
    paths = []
    if p.name != '__init__.py':
        paths.append(p.stem)
    while True:
        p = p.parent
        if not p:
            break
        if not p.is_dir():
            break

        inits = [f for f in p.iterdir() if f.name == '__init__.py']
        if not inits:
            break

        paths.append(p.stem)

    return '.'.join(reversed(paths))

Конечно, есть возможности для улучшения, и необязательные файлы __init__.py могут потребовать других изменений, но если у вас есть __init__.py в целом, это делает свое дело.

0 голосов
/ 10 января 2018

Добавив это в список ответов, я не смог найти ничего, что сработало. Это позволит импортировать скомпилированные (pyd) модули Python в 3.4:

import sys
import importlib.machinery

def load_module(name, filename):
    # If the Loader finds the module name in this list it will use
    # module_name.__file__ instead so we need to delete it here
    if name in sys.modules:
        del sys.modules[name]
    loader = importlib.machinery.ExtensionFileLoader(name, filename)
    module = loader.load_module()
    locals()[name] = module
    globals()[name] = module

load_module('something', r'C:\Path\To\something.pyd')
something.do_something()
0 голосов
/ 25 ноября 2014

Лучший способ, я думаю, из официальной документации ( 29.1. Imp - доступ к внутренним компонентам импорта ):

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()
...