Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-导入给定完整路径的模块目录_Python - Fatal编程技术网

Python-导入给定完整路径的模块目录

Python-导入给定完整路径的模块目录,python,Python,我这里有一个python模块/root/python/foo.py。我在文件夹/root/lib/中还有一堆其他模块,如下所示 lib/ | ├─ module1/ | ├─ __init__.py    | └─ bar.py | └─ module2/ ├─ __init__.py └─ bar.py 我想从foo.py导入/root/lib/module1和/root/lib/module2。我想不必须

我这里有一个python模块
/root/python/foo.py
。我在文件夹
/root/lib/
中还有一堆其他模块,如下所示


    lib/
    |
    ├─ module1/
    |  ├─ __init__.py
    |  └─ bar.py
    |
    └─ module2/
       ├─ __init__.py
       └─ bar.py

我想从
foo.py
导入
/root/lib/module1
/root/lib/module2
。我想必须将
/root/lib/
添加到python系统路径。告诉您如何使用
imp.load\u source
importlib.machine.SourceFileLoader
,或
importlib.util
类从文件加载模块(取决于python版本)。我认为,只有当模块是单个文件时,这些才起作用。如果我在Python 3.4中尝试类似的内容

from importlib.machinery import SourceFileLoader
problem_module = SourceFileLoader('test_mod', '/root/lib/module1').load_module()
我得到一个
isDirectoryError

我的问题是,如果模块是目录,是否有类似的方法加载模块(给定其完整路径),而不将整个
lib/
文件夹添加到系统路径?

尝试:

from importlib.machinery import SourceFileLoader
problem_module = SourceFileLoader('test_mod', '/root/lib/module1/__init__.py').load_module()
\uuuu init\uuuuu.py
应注意同一软件包中的模块:


从中添加
。导入bar
以使
bar.py
成为包的一部分

一些更正:

  • module1
    是一个包而不是一个模块
  • bar.py
    是软件包
    module1

Python并没有为我们提供一种加载无法被
sys.path
引用的文件的简单方法,最常用的解决方案将执行以下操作之一:

  • 将所需路径添加到
    sys.path
  • 重新构造模块,使正确的路径已位于
    sys.path
  • 几乎其他任何一种解决方案都无法解决问题(使用非预期方法完成工作),有些解决方案可能会让人头疼

    然而,python确实提供了一种机制,让我们可以模拟一个包,该包分布在不在
    sys.path
    上的文件夹中,您可以通过在模块中执行以下操作:

    __path__ = ["/root/lib"]
    
    将这一行放在名为
    lib.py
    的文件中,并将其放置在与
    foo.py
    相同的文件夹中,以便由它导入(在您的情况下,在
    root/python/
    中),然后从
    foo.py
    中执行以下操作:

    import lib.module1
    #or
    from lib import module1
    

    这向python指示
    .module1
    子包位于指定的
    \uuuuuuuuuuu路径上的某个位置,并将从该目录(或多个目录)加载使用预期的导入机制并保持您的
    sys.path
    不变。

    在模块1之后添加
    '
    ,您需要使用
    sys.path
    来可靠地导入模块。请参阅,“我不想将/root/lib/添加到python系统路径。”-为什么不?这是迄今为止最简单的方法。我不想将目录添加到系统路径,因为我认为库中可能有数百个模块,并且我认为只针对我想要的文件夹会更好。也许将
    lib
    文件夹添加到系统路径并不像我想的那么糟糕。这样做很有效。我想使用module1作为模块名称,例如,我还想在加载模块1后从模块1导入bar.py。仅仅针对init.py并不能让我这么做。导入bar
    \uuu init\uuu.py
    替代解决方案:
    从.bar导入*
    我不想通过init.py文件导入超过模块。我想从problem_module import bar中做一些类似于
    的事情,但我想如果我必须这样做,那也不会太糟糕,我只需要改变我的工作方式。这对我是一个巨大的帮助,谢谢!我在尝试将文件
    foo.bar.py
    importlib
    作为模块导入时遇到了一个问题。我想你是对的,我可能需要将
    lib
    文件夹添加到system.path中。但是如果这是正确的方法,那么我想知道为什么python允许您导入一个模块,如果它只是一个使用
    SourceFileLoader
    (在python 3.4中)的文件。如果他们有这个功能,你会认为它是一个文件还是一个目录都不重要<代码>源代码
    文件
    加载程序
    ,您没有指定文件,从源代码加载单个模块并不像整个导入机制那么简单,因此我不会指望它在任何情况下都能100%工作。是的,我只是想知道为什么在有
    SourceFileLoader
    的情况下没有
    SourceDirectoryLoader
    方法。但我想你是对的,这并不像使用导入机制那么简单。@pspencer我刚刚找到了一个使用预期机制的实际解决方案,我想这正是你所需要的。@Tadhq McDonald Jensen就是你刚才提到的关于
    \uuuuu路径\uuuu
    特殊名称的编辑的解决方案?这是python的一个非常有趣的特性,我不知道,但这正是我想要的。我正在寻找一种类似SourceFileLoader的方法,但它只适用于目录。我认为我从这次讨论中得出的结论是,除了将
    lib
    目录添加到系统路径之外,没有一种好的pythonic方法来做我想要做的事情。