How to accomplish relative import in python
1 2 3 4 5 6 7 8 9 | stuff/ __init__.py mylib.py Foo/ __init__.py main.py foo/ __init__.py script.py |
这只是一个例子,但实际上我只是想在父目录中进行模块的相对导入。 我尝试过各种各样的东西并得到这个错误......
我在某处读到程序启动的脚本不应该在包中,我尝试修改结构就像这样......
1 2 3 4 5 6 | stuff/ mylib.py foo.py // equivalent of main.py in above foo/ __init__.py script.py |
但得到了同样的错误。
我怎么能做到这一点? 这甚至是一种适当的方法吗?
编辑:在Python 2中
在稍微摆弄它之后,我意识到如何设置它,为了特异性,我不会使用foo bar名称。我的项目目录设置为...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | tools/ core/ object_editor/ # files that need to use ntlib.py editor.py # see example at bottom __init__.py state_editor/ # files that need to use ntlib.py __init__.py ntlib.py __init__.py # core is the top level package LICENSE state_editor.py # equivalent to main.py for the state editor object_editor.py # equivalent to main.py for the object editor |
1 | from core.object_editor import editor |
1 | from .. import ntlib |
或者
1 | from core import ntlib |
关键是在我给出的问题示例中,"main"脚本是从包中运行的。一旦我把它移出去,创建了一个特定的包(
虽然你的python PATH中没有长的"东西",但你别无选择,只能添加路径。
如果你从你可以做的东西中知道你的script.py的级别,例如:
1 2 3 | import sys import os sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) |
我正在Windows 7上运行Python 3.4.2并且在我身上撕掉我的头发。
运行以下任何一个时:
python -m unittest
python -m unittest discover
...我会得到'尝试相对导入超出顶级包'错误。
对我来说,解决方案是在我的[test_stock.py]中删除".."。
这条线是:
来自..stock进口库存
将其更改为:
从库存进口库存
..而且它有效。
文件夹结构:
1 2 3 4 5 6 7 8 9 10 11 | C:\ | +-- stock_alerter | +-- __init__.py +-- stock.py | \-- tests | +-- __init__.py \-- test_stock.py |
从PEP看来,您无法使用相对导入来导入未打包的文件。
因此,您需要在内容中添加
但是,PEP似乎没有考虑将mylib打包在一个模块中。因此,您可能需要更改调用库函数的方式。
另一种方法是将mylib移动到子包中并将其作为
编辑取消了扩展
如果你使用的是Linux或类似的* nix,你可以使用符号链接来解决这个问题。
1 2 3 4 5 6 7 8 9 | stuff/ mylib.py foo.py // equivalent of main.py in above foo/ script.py mylib.py -> ../mylib.py foo2/ script2.py mylib.py -> ../mylib.py |
这可能不是一个好的模式。
在我的情况下,我选择了它,因为我有多个可执行文件依赖于需要放入不同目录的同一个库。
新的可执行测试的实现不应该要求测试编写者对python导入有深入的了解。
1 2 3 4 5 6 7 8 9 10 11 | tests/ common/ commonlib.py test1/ executable1.py executable2.py commonlib.py -> ../common/commonlib.py test2/ executable1.py executable2.py commonlib.py -> ../common/commonlib.py |