将 Python 中的模块作为包的一部分*以及*以独立工作的方式导入

Importing a module in Python as part of a package *as well* as in a way that works stand-alone

注:这是Python3.5

给定一些项目 thing 这样:

   thing/
       top.py (imports bar)
       utils/
           __init__.py (empty)
           bar.py (imports foo; has some functions and variables)
           foo.py (has some functions and variables)

我可以import utils.bartop.py,运行宁top.py 文件 bar.py 必须包含 import utils.foo 才能获得 foo.py 的代码。

到运行bar.py直接虽然,bar.py必须有import foo 而不是(import utils.foo 失败)。如果我进行更改,那么 top.py 将不再有效。

我怎样才能 运行 top.py 或 bar.py 并且仍然在 bar.py 中对两种用例使用相同的导入结构? 我觉得我错过了一些简单的步骤或构造,但也许期望 bar.py 以这种方式独立工作要求太多(缺少条件导入等)。

编辑:我已经接受了正确的答案,但是如果你仍然坚持做一些扭曲,以下对我有用

bar.py

try:
    import foo
except ImportError as err:
    from . import foo

然后你可以 运行 bar.py 直接(在我的例子中,当我开发 bar.py 我正在使用一些实验代码文件底部的 if __main__ 块)。一旦我的代码很好地集成,我删除条件和 main 部分(因为它并不意味着 运行 独立)。

https://docs.python.org/2.5/whatsnew/pep-328.html try to use import .foo and for python 3 see Relative imports in Python 3

通常将所有入口点都放在模块外部,而不是所有导入都是相对的。 例如

thing/
    app.py
    thing/
        __init__.py
        top.py
        utils/
            __init__.py
            bar.py
            foo.py

而app.py可以看起来像

from thing import app
if __name__ == '__main__':
    app.main()

比 top.py 你有

from .utils import bar

在酒吧你有

from . import foo

from thing.utils import foo

from ..utils import foo

因此,如果您需要两个入口点,您可以让 app 为第二个入口点采用命令行参数,或者您可以制作另一个文件,例如导入 bar

的应用程序