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.
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 .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
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
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
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 +
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')
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
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ę.
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.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
.
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.
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)
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.
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)
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
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)
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!
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 *
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
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ę
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.
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()
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ę.
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()
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