【问题标题】:How can I import a python package or __init__.py file using the full path?如何使用完整路径导入 python 包或 __init__.py 文件?
【发布时间】:2015-06-18 16:52:05
【问题描述】:

我有一个包:pyfoo 在 /home/user/somedir 目录中

包装是普通的 '/home/user/somedir/pyfoo/__init__.py'

我希望能够使用其完整路径“/home/user/somedir/pyfoo/”导入此模块

如何为非包模块执行此操作如下所示: How to import a module given the full path?

但是当模块是一个包时,我似乎无法让它工作。


为此我发现的一个非常奇怪的用例是,在使用 h5py 写入文件之前,我被深深嵌入到脚本执行中。

我不得不卸载 h5py 并使用 openmpi 重新安装并行版本,但即使已卸载 h5py(serial) 仍在内存中。我不想重新启动,因为脚本花了很长时间。我试图重新加载模块,但它不起作用。我还尝试使用目录和 __init__.py 从其文件名中导入它,但我遇到了相对导入错误。我什至尝试将新的安装位置添加到 sys.path 并执行正常导入,但这也失败了。

我的个人实用程序库中已经有一个 import_from_filepath 函数,我也想添加 import_from_dirpath ,但我在弄清楚它是如何完成的时遇到了一些麻烦。


这是一个说明问题的脚本:

    # Define two temporary modules that are not in sys.path
    # and have the same name but different values.
    import sys, os, os.path
    def ensuredir(path):
        if not os.path.exists(path):
            os.mkdir(path)
    ensuredir('tmp')
    ensuredir('tmp/tmp1')
    ensuredir('tmp/tmp2')
    ensuredir('tmp/tmp1/testmod')
    ensuredir('tmp/tmp2/testmod')
    with open('tmp/tmp1/testmod/__init__.py', 'w') as file_:
        file_.write('foo = \"spam\"\nfrom . import sibling')
    with open('tmp/tmp1/testmod/sibling.py', 'w') as file_:
        file_.write('bar = \"ham\"')
    with open('tmp/tmp2/testmod/__init__.py', 'w') as file_:
        file_.write('foo = \"eggs\"\nfrom . import sibling')
    with open('tmp/tmp1/testmod/sibling.py', 'w') as file_:
        file_.write('bar = \"jam\"')

    # Neither module should be importable through the normal mechanism
    try:
        import testmod
        assert False, 'should fail'
    except ImportError as ex:
        pass

    # Try temporarilly adding the directory of a module to the path
    sys.path.insert(0, 'tmp/tmp1')
    testmod1 = __import__('testmod', globals(), locals(), 0)
    sys.path.remove('tmp/tmp1')
    print(testmod1.foo)
    print(testmod1.sibling.bar)

    sys.path.insert(0, 'tmp/tmp2')
    testmod2 = __import__('testmod', globals(), locals(), 0)
    sys.path.remove('tmp/tmp2')
    print(testmod2.foo)
    print(testmod2.sibling.bar)

    assert testmod1.foo == "spam"
    assert testmod1.sibling.bar == "ham"

    # Fails, returns spam
    assert testmod2.foo == "eggs"
    assert testmod2.sibling.bar == "jam"

sys.path 方法不通过文件路径导入。它默认导入之前加载的模块。

【问题讨论】:

  • 您是否尝试将/home/user/somedir/ 附加到sys.path
  • 是的,但它似乎不起作用。
  • 你到底尝试了什么?
  • @sirfz 查看我发布的小测试示例。
  • 使用完整路径,并确保你的包目录中有__init__.py

标签: python python-2.7 python-3.x python-import


【解决方案1】:

一般来说,您不会从 Python 中的绝对路径进行导入。这是可能的,但它会破坏该模块中的导入等内容。

您所做的是调整PYTHONPATH。它告诉 python 在哪里寻找你想要导入的东西。您可以在调用脚本之前设置环境变量PYTHONPATH,也可以在运行时查看和操作它。为此,请更改 sys.path。是一个列表,你可以append()其他路径。

另一种选择是使用虚拟环境,它们为不同的项目和项目设置提供特殊的 python 环境。阅读http://docs.python-guide.org/en/latest/dev/virtualenvs/ 了解它。

如果您仍想通过路径导入,请阅读How to import a module given the full path?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多