相对进口的python包装

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4348452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 15:20:42  来源:igfitidea点击:

python packaging for relative imports

pythonpython-import

提问by eerne

First off all: I'm sorry, I know there has been lots of question about relative imports, but I just didn't find a solution. If possible I would like to use the following directory layout:

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

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

Now my questions are:

现在我的问题是:

  • How do the test files from within the package properly import myClass.py?

  • How would you import the package from outside, assuming you take myClass as submodule in libs/myClass or include/myClass?

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

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

So far I couldn't find an elegant solution for this. From what I understand Guido's Decisionit should be possible to do from ..src import myClassbut this will error:

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

ValueError: Attempted relative import in non-package

ValueError: Attempted relative import in non-package

Which looks as it doesn't treat myClass as packages. Reading the docs:

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

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

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

It seems I'm missing something that specifies where the scripts of the package are, should I use .pth ?

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

回答by khachik

Intra-package-referencesdescribes how to myClassfrom test/*. To import the package from outside, you should add its path to PYTHONPATHenvironment variable before running the importer application, or to sys.pathlist in the code before importing it.

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

Why from ..src import myClassfails: probably, srcis not a python package, you cannot import from there. You should add it to python path as described above.

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

回答by Daniel Kluev

ValueError: Attempted relative import in non-package

ValueError: Attempted relative import in non-package

Means you attempt to use relative import in the module which is not package. Its problem with the file which has this from ... importstatement, and not the file which you are trying to import.

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

So if you are doing relative imports in your tests, for example, you should make your tests to be part of your package. This means

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

  1. Adding __init__.pyto test/
  2. Running them from some outside script, like nosetests
  1. 添加__init__.py到测试/
  2. 从一些外部脚本运行它们,比如鼻子测试

If you run something as python myClass/test/demo.py, relative imports will not work too since you are running demo module not as package. Relative imports require that the module which uses them is being imported itself either as package module, from myClass.test.demo import blabla, or with relative import.

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

回答by Sevvy325

After hours of searching last night I found the answer to relative imports in python!! Or an easy solution at the very least. The best way to fix this is to have the modules called from another module. So say you want demo.pyto import myClass.py. In the myClassfolder at the root of the sub-packages they need to have a file that calls the other two. From what I gather the working directory is always considered __main__so if you test the import from demo.pywith the demo.pyscript, you will receive that error. To illustrate:

经过昨晚几个小时的搜索,我找到了 python 中相对导入的答案!!或者至少是一个简单的解决方案。解决此问题的最佳方法是从另一个模块调用模块。所以说你想demo.py导入myClass.py. 在myClass子包根目录的文件夹中,他们需要有一个文件来调用另外两个。从我收集的内容来看,始终考虑工作目录,__main__因此如果您demo.py使用demo.py脚本测试导入,您将收到该错误。为了显示:

Folder hierarchy:

文件夹层次结构:

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

myClass.py:

我的类.py:

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

demo.py:

演示.py:

from ..src import myClass

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

main.py:

主要.py:

import test.demo

demo.printer()

If you run demo.pyin the interpreter, you will generate an error, but running main.pywill not. It's a little convoluted, but it works :D

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