如何导入一个模块给定的完整path?

我怎样才能加载一个Python模块的全path? 请注意,该文件可以位于文件系统的任何位置,因为它是一个configuration选项。

对于Python 3.5+使用:

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

对于Python 3.3和3.4使用:

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

(尽pipe这已经在Python 3.4中被弃用了。)

Python 2使用:

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

编译的Python文件和DLL有相当的便利function。

也可以看看。 http://bugs.python.org/issue21436

向sys.path添加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 

你也可以这样做,将configuration文件所在的目录添加到Python加载path中,然后只要进行正常的导入,假设你事先知道文件的名字,在这里是“config”。

凌乱,但它的作品。

 configfile = '~/config.py' import os import sys sys.path.append(os.path.dirname(os.path.expanduser(configfile))) import config 

你可以使用

 load_source(module_name, path_to_file) 

方法从IMP模块 。

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

你的意思是加载或导入?

你可以操纵sys.path列表指定你的模块的path,然后导入你的模块。 例如,给定一个模块:

 /foo/bar.py 

你可以这样做:

 import sys sys.path[0:0] = '/foo' # puts the /foo directory at the start of your path import bar 

我相信你可以使用imp.find_module()imp.load_module()来加载指定的模块。 你需要将模块名称从path中分离出来,也就是说,如果你想加载/home/mypath/mymodule.py你需要这样做:

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

…但应该完成工作。

这听起来像你不想特别导入configuration文件(这有很多的副作用和其他并发症),你只是想运行它,并能够访问结果命名空间。 标准库以runpy.run_path的forms为其提供专门的API:

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

该接口在Python 2.7和Python 3.2+中可用

以下是一些适用于所有Python版本的代码,从2.7-3.5甚至其他版本。

 config_file = "/tmp/config.py" with open(config_file) as f: code = compile(f.read(), config_file, 'exec') exec(code, globals(), locals()) 

我testing了它。 这可能是丑陋的,但迄今为止,在所有版本中都是唯一的。

这应该工作

 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) 

我并不是说它更好,但是为了完整起见,我想提出一个exec函数,可以在Python 2和Python 3中使用exec允许您在全局范围内或者在内部执行任意代码范围,作为字典提供。

例如,如果使用函数foo()将模块存储在"/path/to/module ”中,则可以通过执行以下操作来运行它:

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

这使得它更加明确,你是dynamic加载代码,并授予你一些额外的权力,如提供自定义内置的能力。

如果通过属性访问,而不是密钥对你很重要,你可以为全局devise一个自定义的dict类,提供这样的访问,例如:

 class MyModuleClass(dict): def __getattr__(self, name): return self.__getitem__(name) 

在运行时导入包模块(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) 

您可以使用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! 

Python 3.4的这个领域似乎是非常曲折的理解! 然而,通过使用Chris Calloway的代码作为开始,我尝试了一些工作。 这是基本的function。

 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中的不推荐使用的模块。 我不假装理解为什么,但似乎在一个程序内工作。 我发现克里斯的解决scheme在命令行上工作,而不是在程序中。

要从给定文件名导入模块,可以临时扩展path,并在finally块引用中恢复系统path:

 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 

我想出了一个稍微修改过的@ SebastianRittau的精彩答案(对于Python我认为是3.4),它允许你使用spec_from_loader而不是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) 

在显式的SourceFileLoader中编码path的好处是机器不会试图从扩展中找出文件的types。 这意味着您可以使用此方法加载类似.txt文件的文件,但是无法使用spec_from_file_location来指定加载器,因为.txt不在importlib.machinery.SOURCE_SUFFIXES

我制作了一个使用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/

在Linux中,在python脚本所在的目录中添加一个符号链接。

即:

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

python会创build/absolute/path/to/script/module.pyc,如果你改变/absolute/path/to/module/module.py内容

然后在mypythonscript.py中包含以下内容

从模块导入*

我认为,最好的办法是从官方文件( 29.1。imp – 访问import内部机构 ):

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

这可能很明显,但在交互式shell中:

 cd path import module