python 中模块的相对路径

relative paths for modules in python

我尝试了一些不同的技术来尝试做一些对我来说似乎可行的事情,但我想我遗漏了一些关于 python 的陷阱(使用 2.7 但希望这也适用于 3.*如果可能的话)。

我不确定包或模块等术语,但对我来说,以下似乎是一个 "simple" 可行的方案。

这是目录结构:

.
├── job
│   └── the_script.py
└── modules
    ├── __init__.py
    └── print_module.py

the_script.py的内容:

# this does not work
import importlib
print_module = importlib.import_module('.print_module', '..modules')

# this also does not work
from ..modules import print_module

print_module.do_stuff()

print_module的内容:

def do_stuff():
    print("This should be in stdout")

我想 运行 所有这些 "relative paths" 东西作为:

/job$ python2 the_script.py

但是 importlib.import_module 给出了各种错误:

另一方面,使用 from ..modules 语法我得到:ValueError: Attempted relative import in non-package.

我认为 __init__.py 空文件应该足以将该代码限定为 "packages"(或模块?不确定术语),但似乎我缺少一些关于如何管理相对路径。

我读到过去有人使用 pathimport osimport sys 中的其他函数破解它,但根据官方文档(python 2.7 和 3.*) 这应该不再需要了。

我做错了什么,我怎样才能打印内容 modules/print_module.do_stuff 从 "relative directory" job/ 中的脚本调用它的结果?

如果您在这里遵循本指南的结构:http://docs.python-guide.org/en/latest/writing/structure/#test-suite(强烈建议您全部阅读,非常有帮助)您将看到:

To give the individual tests import context, create a tests/context.py file:

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import sample

Then, within the individual test modules, import the module like so:

from .context import sample

This will always work as expected, regardless of installation method.

翻译成你的情况是:

root_folder
├── job
│   ├── context.py <- create this file
│   └── the_script.py
└── modules
    ├── __init__.py
    └── print_module.py

context.py 文件中写入上面显示的行,但是 import modules 而不是 import samples

终于在您的 the_script.py 中:from .context import module 您可以开始了!

祝你好运:)

如果您不确定术语,请转到非常好的教程:

http://docs.python-guide.org/en/latest/writing/structure/#modules

http://docs.python-guide.org/en/latest/writing/structure/#packages

但是对于你的结构:

.
├── job
│   └── the_script.py
└── modules
    ├── __init__.py
    └── print_module.py

就在the_script.py中说:

import sys
sys.append('..')
import modules.print_module

这会将父目录添加到 PYTHONPATH,python 会在工作目录中看到目录 'parallel',它会起作用。

我认为在最基本的层面上知道以下内容就足够了:

  1. package 是包含 __init__.py file
  2. 的任何目录
  3. 模块 是一个带有 .py 的文件,但是当您导入模块时,您忽略了扩展名。

我找到了使用 sysos 的解决方案。

脚本 the_script.py 应该是:

import sys
import os
lib_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../modules'))
sys.path.append(lib_path)

# commenting out the following shows the `modules` directory in the path
# print(sys.path)

import print_module

print_module.do_stuff()

然后我可以通过命令行 运行 无论我在路径中的什么位置,例如:

  • /job$ python2 the_script.py
  • <...>/job$ python2 <...>/job/the_script.py