从更高级别的软件包中导入Python模块

问题描述:

这是我的包裹层次结构

app  
|--__init__.py    //Empty file
|--server.py  
|--global_vars.py  
|
|--handlers    
   |--__init__.py    //Empty file
   |
   |--url1
   |  |--__init__.py    //Empty file
   |  |--app1.py
   |  |--app2.py
   |
   |--url2
      |--__init__.py    //Empty file
      |--app3.py

现在,我想在app1.py中导入global_vars.py. 所以我给了 import app.global_vars.py位于app1.py中.

Now I want to import global_vars.py inside app1.py. So I gave import app.global_vars.py inside app1.py.

但是出现以下错误:

    import app.global_vars
ImportError: No module named app.global_vars

我还应该提到我是从server.py导入app1.py的. server.py是我实际上正在运行的文件.当server.py导入app1.py时,app1.py尝试导入global_vars.py,并且出现上述错误

I should also mention that I am importing app1.py from server.py. server.py is the file I am actually running. When server.py imports app1.py, app1.py tries to import global_vars.py and I get the above mentioned error

我在做什么错了?

如果将app/server.py作为脚本运行,则app的父目录不会添加到sys.path().而是添加app目录本身(不是作为软件包,而是作为导入搜索路径).

If you are running app/server.py as a script, the parent directory of app is not added to sys.path(). The app directory itself is added instead (not as a package but as a import search path).

您有4个选择:

  1. server.py 移出app程序包(在其旁边)
  2. 在仅运行的app旁边添加一个新的脚本文件:

  1. Move server.py out of the app package (next to it)
  2. Add a new script file next to app that only runs:

from app import server
server.main()

  • 使用 -m开关选项运行 module 作为主要入口点:

  • Use the -m switch option to run a module as the main entry point:

    python -m app.server
    

  • server.py的父目录添加到sys.path:

  • Add the parent directory of server.py to sys.path:

    import os.path
    import sys
    
    parent = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0, parent)
    

    这最后一个选项可能会带来更多问题;现在app软件包和app软件包中 中包含的模块都在sys.path上.您可以同时导入app.serverserver,Python将把它们看作两个独立的模块,每个模块在sys.modules中都有自己的条目,并带有各自的全局变量的单独副本.

    This last option can introduce more problems however; now both the app package and the modules contained in the app package are on sys.path. You can import both app.server and server and Python will see these as two separate modules, each with their own entry in sys.modules, with separate copies of their globals.