71

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

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

现在我的问题是:

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

  • 假设您将 myClass 作为 libs/myClass 或 include/myClass 中的子模块,您将如何从外部导入包?

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

ValueError: Attempted relative import in non-package

看起来它没有将 myClass 视为包。阅读文档

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

似乎我遗漏了一些指定包脚本在哪里的东西,我应该使用 .pth 吗?

4

3 回答 3

42

ValueError: Attempted relative import in non-package

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

因此,如果您在测试中进行相对导入,例如,您应该让您的测试成为您的包的一部分。这表示

  1. 添加__init__.py到测试/
  2. 从一些外部脚本运行它们,比如鼻子测试

如果您将某些东西作为 运行python myClass/test/demo.py,则相对导入也将不起作用,因为您运行的是演示模块而不是包。相对导入要求使用它们的模块本身作为包模块from myClass.test.demo import blabla导入,或者使用相对导入。

于 2010-12-04T03:15:48.013 回答
28

经过昨晚几个小时的搜索,我找到了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

我的类.py:

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

演示.py:

from ..src import myClass

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

主要.py:

import test.demo

demo.printer()

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

于 2012-05-23T03:59:34.950 回答
0

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

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

于 2010-12-03T18:19:57.670 回答