python包导入相关

python packaging for relative imports

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

1
2
3
4
5
6
7
8
9
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当作包来对待。阅读文档:

The __init__.py files are required to make Python treat the directories as containing packages;

似乎我遗漏了一些指定包脚本位置的内容,应该使用.pth吗?


ValueError: Attempted relative import in non-package

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

因此,例如,如果您在测试中进行相对导入,那么应该使测试成为包的一部分。这意味着

  • 添加__init__.py进行测试/
  • 从外部脚本运行它们,比如nosetest
  • 如果您以python myClass/test/demo.py的形式运行某些内容,则相对导入也不会工作,因为您运行的是演示模块而不是包。相对导入要求使用它们的模块本身作为包模块、from myClass.test.demo import blabla或相对导入进行导入。


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

    文件夹层次结构:

    1
    2
    3
    4
    5
    6
    7
    8
    myClass/
        main.py #arbitrary name, can be anything
        test/
            __init__.py
            demo.py
        src/
            __init__.py
            myClass.py

    MyCase.Py:

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

    Dimo.Py:

    1
    2
    3
    4
    from ..src import myClass

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

    MY.PY:

    1
    2
    3
    import test.demo

    demo.printer()

    如果在解释器中运行demo.py,将生成错误,但运行main.py将不会。这有点复杂,但很有效:d


    包内引用描述了如何从test/*myClass。要从外部导入包,您应该在运行导入程序应用程序之前将其路径添加到PYTHONPATH环境变量,或者在导入包之前将其添加到代码中的sys.path列表。

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