用于相对进口的python包装

时间:2010-12-03 18:05:41

标签: python python-import

首先关闭所有人:对不起,我知道有很多关于相关进口的问题,但我找不到解决方案。如果可能,我想使用以下目录布局:

myClass/
    __init__.py
    test/
        demo.py
        benchmark.py
        specs.py
    src/
        __init__.py
        myClass.py

现在我的问题是:

  • 如何从包中的测试文件正确导入myClass.py?

  • 如果你将libC / myClass或include / myClass中的myClass作为子模块,你将如何从外部导入包?

到目前为止,我找不到一个优雅的解决方案。根据我的理解Guido's Decision,应该可以from ..src import myClass,但这会出错:

ValueError: Attempted relative import in non-package

看起来它不会将myClass视为包。 Reading the docs

  

需要__init__.py文件才能使Python将目录视为包含包;

我似乎缺少一些指定包的脚本的东西,我应该使用.pth吗?

3 个答案:

答案 0 :(得分:42)

  

ValueError: Attempted relative import in non-package

表示您尝试在非包的模块中使用相对导入。它存在具有此from ... import语句的文件的问题,而不是您尝试导入的文件。

因此,例如,如果您在测试中进行相对导入,则应将测试作为包的一部分。这意味着

  1. __init__.py添加到test /
  2. 从一些外部脚本运行它们,例如nosetests
  3. 如果以python myClass/test/demo.py运行某些内容,由于您运行演示模块而不是包,因此相对导入也不会起作用。相对导入要求使用它们的模块本身作为包模块from myClass.test.demo import blabla或相对导入导入。

答案 1 :(得分:27)

昨晚经过几个小时的搜索,我找到了python中相对进口的答案!!或者至少是一个简单的解决方案。解决此问题的最佳方法是从另一个模块调用模块。因此,您希望demo.py导入myClass.py。在子包根目录的myClass文件夹中,他们需要有一个调用其他两个文件的文件。从我收集的工作目录始终被视为__main__,因此如果您使用demo.py脚本测试demo.py的导入,您将收到该错误。举例说明:

文件夹层次结构:

myClass/
    main.py #arbitrary name, can be anything
    test/
        __init__.py
        demo.py
    src/
        __init__.py
        myClass.py

myClass.py:

def randomMaths(x):
    a = x * 2
    y = x * a
    return y

demo.py:

from ..src import myClass

def printer():
    print(myClass.randomMaths(42))

main.py:

import test.demo

demo.printer()

如果您在解释器中运行demo.py,则会产生错误,但不会运行main.py。这有点令人费解,但它有效:D

答案 2 :(得分:0)

Intra-package-references介绍了如何myClass来自test/*。要从外部导入包,您应该在运行导入器应用程序之前将其路径添加到PYTHONPATH环境变量,或者在导入之前将其添加到代码中的sys.path列表。

为什么from ..src import myClass失败:可能src不是python包,你不能从那里导入。您应该将它添加到python路径,如上所述。