简体   繁体   English

Python-导入具有完整路径的模块目录

[英]Python - import a module directory given full path

I have a python module here /root/python/foo.py . 我在/root/python/foo.py有一个python模块。 I have a bunch of other modules here in the folder /root/lib/ which looks like this 我在文件夹/root/lib/中还有很多其他模块,看起来像这样


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

I would like to import /root/lib/module1 and /root/lib/module2 from foo.py . 我想从foo.py导入/root/lib/module1/root/lib/module2 I would like to not have to add /root/lib/ to the python system path. 不想不必将/root/lib/添加到python系统路径。 This stack overflow answer tells you how to use either imp.load_source , importlib.machinery.SourceFileLoader , or the importlib.util class to load a module from a file (depending on the python version). 这个堆栈溢出答案告诉您如何使用imp.load_sourceimportlib.machinery.SourceFileLoaderimportlib.util类从文件加载模块(取决于python版本)。 I think these only work if the module is a single file. 我认为这些仅在模块是单个文件的情况下有效。 If I try something like this in Python 3.4 如果我在Python 3.4中尝试类似的方法

from importlib.machinery import SourceFileLoader
problem_module = SourceFileLoader('test_mod', '/root/lib/module1').load_module()

I get an IsADirectoryError 我收到一个IsADirectoryError

My question is whether there is a similar way to load a module (given its full path) if it is a directory, without adding the whole lib/ folder to the system path? 我的问题是,如果它是目录,是否有类似的方式加载模块(给出其完整路径),而没有将整个lib/文件夹添加到系统路径中?

try: 尝试:

from importlib.machinery import SourceFileLoader
problem_module = SourceFileLoader('test_mod', '/root/lib/module1/__init__.py').load_module()

the __init__.py should take care about the modules in the same package: __init__.py应该注意同一包中的模块:

add from . import bar from . import bar添加from . import bar from . import bar to make bar.py part of the package. from . import bar以使bar.py成为软件包的一部分。

Some corrections: 一些更正:

  • module1 is a package not a module. module1是软件包而不是模块。
  • bar.py is a module part of the package module1 bar.py是封装的模块部件module1

Python does not give us an easy way to load files that cannot be referenced by sys.path , most usual solution will do one of the following things: Python无法为我们提供一种简单的方式来加载sys.path无法引用的文件,大多数常用解决方案将执行以下操作之一:

  1. Add desired paths to sys.path or 将所需的路径添加到sys.path
  2. Restructure your modules so that the correct path is already on sys.path 重组模块,以使正确的路径已在sys.path

Nearly all other solutions that does not do either will be work arounds (using non-intended methods to get the job done) and some can cause quite a headache. 几乎所有其他两种都不使用的解决方案都可以解决(使用非预期的方法来完成工作),并且有些解决方案可能会令人头疼。

However python does give us a mechanic that lets us simulate a package that is spread out across folders that are not held on sys.path , you can do this by specifying a __path__ special name in a module: 但是python确实为我们提供了一种机制,可以让我们模拟分布在sys.path上没有的文件夹中的软件包,您可以通过在模块中指定__path__特殊名称来做到这一点:

__path__ = ["/root/lib"]

Put this line in a file called lib.py and place it in the same folder as foo.py to be imported by it (so in root/python/ in your case) then from foo.py you can do this as you would expect: 将此行放在名为lib.py的文件中,并将其与要导入的foo.py放在同一文件夹中(因此,在您的情况下为root/python/ ),然后从foo.py可以执行此操作:

import lib.module1
#or
from lib import module1

This indicates to python that the .module1 subpackage is located somewhere on the specified __path__ and will be loaded from that directory (or multiple directories) using the intended import mechanisms and keeping your sys.path unaltered. 这向python指示.module1.module1位于指定的__path__上的某个__path__ ,并将使用预期的导入机制从该目录(或多个目录)加载,并保持sys.path不变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM