如何在python中完成相对导入

ran*_*dom 23 python relative-path python-2.x python-packaging

stuff/
    __init__.py
    mylib.py
    Foo/
        __init__.py
        main.py
        foo/
            __init__.py
            script.py
Run Code Online (Sandbox Code Playgroud)

script.py 想要导入 mylib.py

这只是一个例子,但实际上我只是想在父目录中进行模块的相对导入.我尝试过各种各样的东西并得到这个错误......

Attempted relative import beyond toplevel package

我在某处读到程序启动的脚本不应该在包中,我尝试修改结构就像这样......

stuff/
    mylib.py
    foo.py // equivalent of main.py in above
    foo/
        __init__.py
        script.py
Run Code Online (Sandbox Code Playgroud)

但得到了同样的错误.

我怎么能做到这一点?这甚至是一种适当的方法吗?

编辑:在Python 2中

ran*_*dom 28

在稍微摆弄它之后,我意识到如何设置它,并且为了特异性,我不会使用foo bar名称.我的项目目录设置为...

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
Run Code Online (Sandbox Code Playgroud)

一条线object_editor.py看起来像......

from core.object_editor import editor
Run Code Online (Sandbox Code Playgroud)

一条线editor.py看起来像......

from .. import ntlib
Run Code Online (Sandbox Code Playgroud)

或者

from core import ntlib
Run Code Online (Sandbox Code Playgroud)

关键是在我给出的问题示例中,"main"脚本是从包中运行的.一旦我把它移出去,创建了一个特定的包(core),并移动了库,我希望编辑器共享(ntlib)到该包中,一切都是hunky-dory.

  • 你有它.发生的事情是您不能使用从命令行运行的脚本中的相对导入,因此应该位于组织的顶层,引用它下面的内容. (2认同)

Tor*_*cht 11

虽然你的python PATH中没有长的"东西",但你别无选择,只能添加路径.

如果你从你可以做的东西中知道你的script.py的级别,例如:

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
Run Code Online (Sandbox Code Playgroud)

  • 这是在某处记录的吗?并不是说我不相信你,但只是想说"嘿从2个目录导入"需要修改系统路径,我必须亲眼看到它. (9认同)

小智 7

我正在Windows 7上运行Python 3.4.2并且在我身上撕掉我的头发.

运行以下任何一个时:

python -m unittest python -m unittest discover

...我会得到'尝试相对导入超出顶级包'错误.

对我来说,解决方案是在我的[test_stock.py]中删除"..".该行是:从..stock进口股票

将其更改为:从库存进口库存

..而且它有效.

文件夹结构:

C:\
  |
  +-- stock_alerter
             |
             +-- __init__.py
             +-- stock.py
             |
             \-- tests
                   |
                   +-- __init__.py
                   \-- test_stock.py
Run Code Online (Sandbox Code Playgroud)