如何编写 __init__.py(也许 __main__.py)文件以避免 import ModuleNotFoundError

How to write __init__.py (and perhaps __main__.py) file to avoid import ModuleNotFoundError

我以为我已经理解了导入系统,但是我很难理解一个看似微不足道的案例:我有一个非常简单的 Python 应用程序,其结构如下:

.
└── myapp
    ├── __init__.py
    ├── lib.py
    └── myapp.py

lib.py的内容是一个平凡的函数:

def funct():
    print("hello from function in lib")

myapp.py应该是应用程序的入口点:

import lib  

def main():
    lib.funct()

if __name__ == "__main__":
    print("calling main")
    main()

当我 运行 主脚本运行时:

> python myapp/myapp.py
calling main
hello from function in lib

但是,例如,当我只是从 IPython 导入包时,它失败了:

In [2]: import myapp
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-2-cabddf3cb27d> in <module>
----> 1 import myapp

~/test/myapp/__init__.py in <module>
----> 1 import myapp.myapp

~/test/myapp/myapp.py in <module>
----> 1 import lib
      2 
      3 
      4 def main():
      5     lib.funct()

ModuleNotFoundError: No module named 'lib'

为什么会这样?最后,我希望我的应用程序可以 python -m myapp 执行,但也可以导入。

默认情况下,import 路径 上搜索模块 sys.path 和其中之一当前目录的路径 so
当你执行主脚本时:

python myapp/myapp.py

myapp.py 文件中的 import 在其当前目录中搜索 lib 模块,即“myapp”和 lib.py在同一目录下,完美执行

但是当您将 myapp 作为包导入 IPython 时,
myapp.py 文件中的 importIPython 的 路径搜索,其中 Lib.py 不存在,因此经典 no module found.

您在这里可以做的事情很少

  1. 使用 myapp.py 中的相关路径 like

    from . import lib
    注意:如果您直接将 myapp.py 作为脚本执行,这将产生错误,因此请相应地处理

  2. 通过附加 lib.py 的路径 [=49] 来更新 sys.path =](不推荐)

    sys.path.append("....../lib.py")

watch this 为了清楚理解。

还要指出,__name__==__main__" 只有当你直接执行文件。所以 myapp.py 中的 if 中的代码在将它用作包中的模块时将不起作用。

希望对您有所帮助:)