如何在模块和主模块中使用相对导入

时间:2013-02-05 12:24:13

标签: python python-2.7 import

我在python中有以下库设置:

library
  | - __init__.py
  | - lib1.py
  | - ...
  | - tools
        | - __init__.py
        | - testlib1.py

所以换句话说,目录library包含python模块,目录toolslibrary的子目录,包含例如testlib1.py。一个文件lib1.py来测试库testlib1.py

lib1.py因此需要从上面的目录中导入python testlib1.py以进行一些测试等,只需从计算机上的某个位置调用PYTHONPATH,假设文件位于搜索路径中。 另外,我只想要指定一个testlib1.py

但是我们都知道from .. import lib1 ... do something with lib1 的以下想法不起作用,因为相对导入不起作用:

testlib1.py

我接受两种答案:

  1. 一个答案,描述了如何直接调用project作为执行python脚本。
  2. 解释模块等更好的概念设置的答案,前提是所有内容都必须位于目录{{1}}中且工具必须位于不同的目录中比实际的图书馆。
  3. 如果某些事情不明确,我建议您提问,我会更新问题。

3 个答案:

答案 0 :(得分:0)

尝试将__init__.py添加到tools目录。相对导入应该有效。

答案 1 :(得分:0)

你做不到。如果您计划使用相对导入,则无法自行运行模块。 放弃相对导入或放弃直接运行testlib1.py的想法。

另外我认为测试文件永远不应该使用相对导入。测试应检查库是否有效,因此代码应尽可能与用户实际使用的代码相似。通常用户不会向库中添加文件以使用相对导入,而是使用绝对导入。

顺便说一句,我认为你的文件组织太“类似java”了:混合源代码和测试。如果你想做测试,那么为什么不能这样:

project/
   |
   +-- src/
   |    |
   |    +--library/
   |    |     |
   |    |     +- lib1.py
   |    |     |
   |    |    #...
   |    +--library2/ #etc.
   |
   +-- tests/
        |
        +--testlibrary/
        |      |
        |      +- testlib1.py
        #etc

要运行测试,只需使用像nosetests这样的工具,它会自动查找这种文件夹结构并提供大量选项来更改搜索/测试设置。

答案 2 :(得分:0)

实际上,我找到了一个解决方案,

  1. 适用于当前的实施
  2. 不需要PYTHONPATH
  3. 中的任何更改
  4. 无需对top-lebel目录进行硬编码
  5. testlib1.py中,以下代码将执行(已经过测试):

    import os
    import sys
    dirparts = os.path.dirname(os.path.abspath(__file__)).split('/')
    sys.path.append('/'.join(dirparts[:-1]))
    
    import  mylib1
    

    不完全确定这是一个非常干净或简单的解决方案,但它允许从目录中导入任何模块一级,这是我需要的(因为测试代码或额外的代码或者tetever总是位于下面一层)实际的模块文件)。