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

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


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


当前回答

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

您可以操作sys.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)来加载指定的模块。您需要将模块名称从路径中分离出来,即,如果要加载/home/mypath/mymodule.py,则需要执行以下操作:

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

…但这应该能完成任务。

可以使用__import__和chdir执行此操作:

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 Exception as e:
        raise ImportError(e)
    return module_obj


import_file('/home/somebody/somemodule.py')

一个使用importlib而不是imp包的简单解决方案(针对Python 2.7进行了测试,尽管它也适用于Python 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")

现在您可以直接使用导入模块的名称空间,如下所示:

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

这种解决方案的优点是,为了在代码中使用它,我们甚至不需要知道要导入的模块的实际名称。这很有用,例如,如果模块的路径是可配置参数。

Python 3.4的这一部分看起来非常曲折,难以理解!然而,作为一个开始,我使用Chris Calloway的代码进行了一点黑客攻击,我终于找到了一些有用的东西。这是基本功能。

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中未弃用的模块。我不想假装理解为什么,但它似乎在一个程序中起作用。我发现Chris的解决方案在命令行上有效,但在程序内部无效。

我给你做了一个用小鬼的包裹。我称之为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/