4

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

我不确定包或模块之类的术语,但对我来说,以下似乎是一个非常“简单”的可行方案。

这是目录结构:

.
├── 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")

我想将所有这些“相对路径”的东西运行为:

/job$ python2 the_script.py

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

  • 如果我只使用 1 个输入参数..modules.print_module,那么我得到:TypeError("relative imports require the 'package' argument")
  • 如果我使用 2 个输入参数(如上面的示例),那么我得到:ValueError: Empty module name

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

我认为__init__.py空文件应该足以将该代码限定为“包”(或模块?不确定术语),但似乎我在如何管理相对路径方面缺少一些东西。

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

我做错了什么,如何实现打印modules/print_module.do_stuff从“相对目录”中的脚本调用它的内容的结果job/

4

3 回答 3

4

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

要为各个测试提供导入上下文,请创建一个 tests/context.py 文件:

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

import sample

然后,在各个测试模块中,像这样导入模块:

from .context import sample

无论安装方法如何,这将始终按预期工作。

在您的情况下翻译这意味着:

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,您将准备出发!

祝你好运 :)

于 2017-03-19T18:31:51.910 回答
3

我找到了使用sysand的解决方案os

脚本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
于 2017-03-22T20:29:37.470 回答
2

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

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 将看到目录“平行”到作业目录,它会工作。

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

  1. 是任何有__init__.py文件的目录
  2. module是一个带有 的文件.py,但是当您导入模块时,您会省略扩展名。
于 2017-03-19T19:04:14.943 回答