如何加载给定完整路径的Python模块?

请注意,文件可以位于文件系统中用户具有访问权限的任何位置。


另请参阅:如何导入以字符串形式命名的模块?


当前回答

我认为,最好的方法是从官方文件(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()

其他回答

向sys.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

你的意思是装货还是进口?

您可以操作sys.path列表,指定模块的路径,然后导入模块。例如,给定位于以下位置的模块:

/foo/bar.py

你可以这样做:

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

您可以使用pydoc中的importfile

from pydoc import importfile
module = importfile('/full/path/to/module/module.py')
name = module.myclass() # myclass is a class inside your python file

下面是一些适用于所有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())

我测试了它。它可能很难看,但到目前为止,它是唯一一个适用于所有版本的。

为了补充塞巴斯蒂安·里托的回答:至少对于CPython,有pydoc,虽然没有正式声明,但导入文件就是它的作用:

from pydoc import importfile
module = importfile('/path/to/module.py')

PS。为了完整起见,在撰写本文时,这里提到了当前的实现:pydoc.py,我很高兴地说,在xkcd 1987的脉络中,它没有使用第21436期中提到的任何一个实现,至少没有逐字逐句地使用。