Jak zaimportować moduł z pełną ścieżką?

Jak mogę załadować moduł Pythona ze względu na jego pełną ścieżkę? Zauważ, że plik może znajdować się w dowolnym miejscu systemu plików, ponieważ jest to opcja konfiguracyjna.

Author: ferkulat, 2008-09-16

24 answers

Dla Pythona 3.5 + użyj:

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

Dla Pythona 3.3 i 3.4 użyj:

from importlib.machinery import SourceFileLoader

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

(chociaż jest to przestarzałe w Pythonie 3.4.)

Użycie Pythona 2:

import imp

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

Istnieją równoważne funkcje wygody dla skompilowanych plików Pythona i bibliotek DLL.

Zobacz też http://bugs.python.org/issue21436 .
 926
Author: Sebastian Rittau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-07 14:31:23

Zaletą dodawania ścieżki do sys.path (over using imp) jest to, że upraszcza rzeczy podczas importowania więcej niż jeden moduł z jednego pakietu. Na przykład:

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
 324
Author: Daryl Spitzer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:36:16

Możesz również zrobić coś takiego i dodać katalog, w którym znajduje się plik konfiguracyjny do ścieżki ładowania Pythona, a następnie po prostu wykonać normalny import, zakładając, że znasz nazwę pliku z góry, w tym przypadku "config".

Bałagan, ale działa.
configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config
 19
Author: ctcherry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-17 22:38:07

Możesz użyć

load_source(module_name, path_to_file) 

Metoda z modułu imp .

 16
Author: zuber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-11 07:07:34

Wygląda na to, że nie chcesz Specjalnie importować pliku konfiguracyjnego (który ma wiele skutków ubocznych i dodatkowych komplikacji), po prostu chcesz go uruchomić i mieć dostęp do wynikowej przestrzeni nazw. Biblioteka standardowa dostarcza API specjalnie do tego celu w formie runpy.run_path :

from runpy import run_path
settings = run_path("/path/to/file.py")

Ten interfejs jest dostępny w Pythonie 2.7 i Pythonie 3.2 +

 14
Author: ncoghlan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 06:52:17
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')
 10
Author: Chris Calloway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 01:43:04

Masz na myśli załadować czy zaimportować?

Możesz manipulować sys.lista ścieżek określ ścieżkę do modułu, a następnie zaimportuj moduł. Na przykład, dany moduł w:

/foo/bar.py

Możesz zrobić:

import sys
sys.path[0:0] = '/foo' # puts the /foo directory at the start of your path
import bar
 9
Author: Wheat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-09 05:30:00

I believe you can use imp.find_module() oraz imp.load_module() aby załadować określony moduł. Musisz podzielić nazwę modułu ze ścieżki, tzn. jeśli chcesz załadować /home/mypath/mymodule.py, musisz zrobić:

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

...ale to powinno załatwić sprawę.

 8
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-02 11:08:38

Oto kod, który działa we wszystkich wersjach Pythona, od 2.7-3.5, A prawdopodobnie nawet innych.

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())
Przetestowałem to. Może i jest brzydki, ale jak na razie jest jedynym, który działa we wszystkich wersjach.
 7
Author: sorin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-03 10:04:52

Wymyśliłem nieco zmodyfikowaną wersję @SebastianRittau ' s wonderful answer (dla Pythona > 3.4 myślę), która pozwoli Ci załadować plik z dowolnym rozszerzeniem jako moduł za pomocą spec_from_loader zamiast spec_from_file_location:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

Zaletą kodowania ścieżki w jawnym SourceFileLoader czy machinery nie będzie próbował domyślić się, jakiego typu jest plik z rozszerzenia. Oznacza to, że możesz załadować coś w rodzaju .txt pliku za pomocą tej metody, ale nie można tego zrobić za pomocą spec_from_file_location bez podania loadera, ponieważ {[4] } nie jest w importlib.machinery.SOURCE_SUFFIXES.

 6
Author: Mad Physicist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-19 18:13:16

Jeśli twój moduł najwyższego poziomu nie jest plikiem, ale jest zapakowany jako katalog z __init__.py, wtedy przyjęte rozwiązanie prawie działa, ale nie do końca. W Pythonie 3.5+ potrzebny jest następujący kod (zwróć uwagę na dodaną linię zaczynającą się od ' sys.Moduły"): {]}

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

Bez tej linii, gdy exec_module jest wykonywany, próbuje powiązać względny import na twoim najwyższym poziomie __init__.py do nazwy modułu najwyższego poziomu -- w tym przypadku "mymodule". Ale "mymodule" nie jest jeszcze załadowany, więc dostaniesz błąd "SystemError: moduł nadrzędny 'mymodule' nie został załadowany, nie można wykonać względnego importu". Więc musisz powiązać nazwę, zanim ją załadujesz. Powodem tego jest fundamentalny niezmiennik względnego systemu importu: "niezmiennik jest taki, że jeśli masz sys.Moduły ['spam'] i sys.Moduły ["spam.foo'] (tak jak po powyższym imporcie), ten ostatni musi pojawić się jako atrybut foo pierwszego" jak omówiono tutaj.

 5
Author: Sam Grondahl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 15:23:41

To powinno zadziałać

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
Author: Hengjie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-04 04:28:50

Ten obszar Pythona 3.4 wydaje się być niezwykle kręty, aby go zrozumieć! Jednak z odrobiną hakowania przy użyciu kodu od Chrisa Callowaya jako początek udało mi się coś działa. Oto podstawowa funkcja.

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

Wygląda na to, że używa nieaktualnych modułów z Pythona 3.4. Nie udaję, że rozumiem dlaczego, ale wygląda na to, że działa w ramach programu. Okazało się, że rozwiązanie Chrisa działa na linii poleceń, ale nie z wewnątrz programu.

 3
Author: Redlegjed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-12 12:22:56

Nie mówię, że jest lepiej, ale ze względu na kompletność, chciałem zasugerować exec Funkcja, dostępna zarówno w Pythonie 2 jak i 3. exec pozwala na wykonanie dowolnego kodu zarówno w zakresie globalnym, jak i wewnętrznym, dostarczonym jako słownik.

Na przykład, jeśli masz moduł zapisany w "/path/to/module " z funkcją foo(), możesz go uruchomić wykonując następujące czynności:

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

To sprawia, że jest to nieco bardziej wyraźne, że ładujesz kod dynamicznie, i daje Ci dodatkową moc, taką jak możliwość dostarczania niestandardowych builtins.

I jeśli posiadanie dostępu poprzez atrybuty, zamiast kluczy jest dla Ciebie ważne, możesz zaprojektować niestandardową klasę dict dla globals, która zapewnia taki dostęp, np.:]}

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)
 3
Author: yoniLavi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-02 19:57:46

Aby zaimportować moduł z podanej nazwy pliku, możesz tymczasowo rozszerzyć ścieżkę i przywrócić ścieżkę systemową w bloku finally reference:

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
Author: Peter Zhu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-02 11:14:13

Import modułów pakietu w czasie wykonywania (Python recipe)

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
Author: user10370,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-22 02:17:57

Możesz użyć modułu pkgutil (w szczególności walk_packages metoda), aby uzyskać listę pakietów w bieżącym katalogu. Stamtąd jest trywialne użycie importlib Maszyny do importowania modułów, które chcesz:

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!
 2
Author: bob_twinkles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-02 11:04:17

W Linuksie dodanie dowiązania symbolicznego do katalogu, w którym znajduje się skrypt Pythona działa.

Ie:

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

Python utworzy /absolute/path/to/script/module.pyc i zaktualizuje go, jeśli zmienisz zawartość /absolute/path/to/module/module.py

Następnie dołącz następujące w mypythonscript.py

from module import *
 2
Author: user2760152,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 17:21:07

Zrobiłem pakiet, który używa imp dla Ciebie. Nazywam to import_file i tak się go używa:

>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')
Możesz go dostać pod adresem:

Http://pypi.python.org/pypi/import_file

Lub w

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

 1
Author: ubershmekel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-08 19:41:29

Dość prosty sposób: Załóżmy, że chcesz zaimportować plik ze ścieżką względną ../.. / MyLibs/pyfunc.py


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

Ale jeśli uda Ci się to bez straży, możesz w końcu dostać bardzo długą drogę

 1
Author: Andrei Keino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-26 04:52:15

Proste rozwiązanie używając importlib zamiast imp pakietu (testowanego dla Pythona 2.7, chociaż powinien działać również dla Pythona 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")

Teraz możesz bezpośrednio użyć przestrzeni nazw zaimportowanego modułu, w następujący sposób:

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

Zaletą tego rozwiązania jest to, że nie musimy nawet znać rzeczywistej nazwy modułu, który chcemy zaimportować, aby użyć go w naszym kodzie. Jest to przydatne np. w przypadku, gdy ścieżka modułu jest konfigurowalnym argumentem.

 1
Author: Ataxias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-28 02:24:45

Dodanie tego do listy odpowiedzi, ponieważ nie mogłem znaleźć niczego, co zadziałało. Pozwala to na import skompilowanych (pyd) modułów Pythona w wersji 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
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 15:58:46

Ta odpowiedź jest uzupełnieniem odpowiedzi Sebastiana Rittau 'a odpowiadającego na komentarz:" ale co jeśli nie masz nazwy modułu?"Jest to szybki i brudny sposób na uzyskanie prawdopodobnej nazwy modułu Pythona - po prostu idzie w górę drzewa, dopóki nie znajdzie katalogu bez pliku __init__.py, a następnie zamienia go z powrotem w nazwę pliku . Dla Pythona 3.4+ (używa pathlib), co ma sens, ponieważ ludzie Py2 mogą używać" imp " lub innych sposobów względnego importu:

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

Są z pewnością możliwości poprawy, a opcjonalne Pliki __init__.py mogą wymagać innych zmian, ale jeśli masz __init__.py w ogóle, to robi to sztuczkę.

 0
Author: Michael Scott Cuthbert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-08 15:29:30

Najlepszy sposób, myślę, jest z oficjalnej dokumentacji (29.1. imp-Access the import internals):

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()
 -1
Author: Zompa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 12:58:47