如何导入一个模块给定的完整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
或在
在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