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

Posted

技术标签:

【中文标题】Python 从更高级别的包中导入模块【英文标题】:Python import modules from a higher level package 【发布时间】:2013-05-23 02:18:01 【问题描述】:

这是我的包层次结构

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 中。

但我收到以下错误:

    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 并出现上述错误

我在这里做错了什么?

【问题讨论】:

app 中是否有__init__.py 文件? 是的,在给定文件层次结构的所有目录中都有一个__init__.py import app; print app.__file__ 说的是那个模块/包的路径? 我去了应用程序的父文件夹,打开了一个 python shell 并导入了应用程序。现在app.__file__ 给出app/__init__.py 作为输出 不,我希望你在 app1.py 中这样做。 【参考方案1】:

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

您有 4 个选项:

    server.py 移出 app 包(旁边)

    app 旁边添加一个仅运行的新脚本文件:

    from app import server
    server.main()
    

    使用-m switch option 运行一个模块 作为主入口点:

    python -m app.server
    

    server.py的父目录添加到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 中都有自己的条目,并具有各自的全局副本。

【讨论】:

感谢您的帮助。现在,我明白了这个问题。【参考方案2】:

需要__init__.py文件,将其视为一个包

应用程序 |--server.py |--global_vars.py |--处理程序

|--__init__.py ...

__init__.py 可以为空

【讨论】:

在给定文件层次结构的所有目录中都有一个__init__.py

以上是关于Python 从更高级别的包中导入模块的主要内容,如果未能解决你的问题,请参考以下文章

python 中导入redis模块

如何导入python中的模块

我无法使用 PythonKit 在 Xcode 11 中导入 Python 模块

如何从包内的两个不同文件夹中导入一个模块,该模块导入另一个模块

python如何删除已在shell中导入的模块?

python中导入模块/包的几种方式