首页 文章

用于相对进口的python包装

提问于
浏览
70

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

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 回答

  • 42

    ValueError:在非包中尝试相对导入

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

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

    • 添加 __init__.py 以测试/

    • 从一些外部脚本运行它们,比如nosetests

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

  • 0

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

  • 26

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

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

相关问题