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 |
现在我的问题是:
到目前为止,我还没有找到一个很好的解决办法。据我所知,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吗?
- @布伦特·纽尼,是的,你是对的,相对进口似乎是一个持续的话题,在阅读了很多答案之后,我仍然感到有必要具体描述一下我的情况。在展示了这个Q之后,在python irc通道上,很多人建议使用平面目录结构:"很多人抵制python使用目录和文件来获取语义名称空间信息的方式。最好是屈服,做Python想要做的事情。"jcalderone.livejournal.com/39794.html
- 有人能提供一些现实世界的包的链接,以示例性的目录布局,或者遵循一些约定吗?(最好在Github上)
- 在test目录中有__init__.py吗?ValueError: Attempted relative import in non-package可能与之有关。
- stackoverflow.com/questions/1803292/…docs.python.org/distutils/examples.html
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
- 我使用的是python 2.7,我只需要做三件事就可以完成上面的代码。首先,在main.py所在的级别,我添加了一个__init__.py。其次,我把demo.printer()改为test.demo.printer()。第三,我更改了main.py上面的目录,运行python -m myClass.main。否则,这是一个非常有帮助的答案。:)
包内引用描述了如何从test/*到myClass。要从外部导入包,您应该在运行导入程序应用程序之前将其路径添加到PYTHONPATH环境变量,或者在导入包之前将其添加到代码中的sys.path列表。
为什么from ..src import myClass失败:可能,src不是python包,您不能从那里导入。您应该像上面描述的那样将它添加到python路径中。
- 相对导入一直都在进行。许多包装中都有更小的子包装,并且依赖于相对进口。OP没有询问如何引用外部包。他在问如何引用一个包中的另一个子包。