【问题标题】:Making every module in a package accessible from within?使包中的每个模块都可以从内部访问?
【发布时间】:2012-09-10 13:09:38
【问题描述】:

应该如何构建 Python 包以使其内部的任何模块都成为可能?

我的文件结构如下:

Project/
    |---log/
    |   |---some logs
    |
    |---src/
        |---foo/
        |   |---__init__.py
        |   |---analyse.py
        |   |---export.py
        |    
        |---bar/
        |   |---__init__.py
        |   |---log.py
        |   |---dbhandler.py
        |   
        |---__init__.py
        |---main.py

main.py 初始化所有内容。我想将foo/analyse.py导入bar/dbhandler.py,但我只收到错误:

AttributeError: 'module' object has no attribute 'analyse'

我尝试了几种说法:

import Project.src.foo.analyse
import src.foo.analyse
import foo.analyse
import analyse

它们都给出相同的错误。我也试过:

from .. import foo.analyse
from .. import analyse

但我收到了:

ValueError: Attempted relative import beyond toplevel package

我已经浏览了 StackOverflow 上的大约 50 个线程和互联网上的无数文章。从我发现的所有内容中,import src.foo.* 语句应该可以在包内的任何位置工作,如果每个文件夹中只有 __init__.py 文件。

有人遇到过同样的问题吗?

【问题讨论】:

  • “我想将 foo/analysis.py 导入 bar/dbhandler.py”是什么意思?您是否尝试在bar/dbhandler.py 中输入import foo.analyse?或者您是否尝试将它们都导入main.py

标签: python package directory-structure relative-import


【解决方案1】:

鉴于您的目录结构,您应该在 main.py 上拥有:

import foo.analyse
import bar.dbhandler

然后像这样调用(例如):

foo.analyse.number_cruncher()
bar.dbhandler.db_store()

如果您从main.py 所在的目录启动程序,它应该可以正常运行。否则,您应该按照 Nicola Musatti 的建议检查您的 PYTHONPATH,或使用 .pth 文件或您拥有的众多选项中的任何一个。

【讨论】:

    【解决方案2】:

    确保您的 PYTHONPATH 包含 Project/src,然后使用

    import foo.analyse
    

    【讨论】:

    • 问题在于添加它为时已晚。现在它工作正常。我将它附加在 src.__init__.py 文件的开头
    【解决方案3】:

    我觉得应该是的

    from ..foo import analyse
    

    由于尚未确定 .. 本身的含义:这可能只是指顶级包,因此您必须说明要向下移动包树的哪个其他分支:foo 在这种情况下。

    这样,我可以做到(前提是src 在您的PYTHONPATH 上。在这种情况下,我刚从Project 目录级别开始):

    >>> import src
    >>> import src.bar
    >>> import src.bar.dbhandler
    >>> src.bar.dbhandler.analyse
    <module 'src.foo.analyse' from 'src/foo/analyse.py'>
    >>> src.bar.dbhandler.analyse.__file__
    'src/foo/analyse.py'
    

    此外,您可能会注意到,在您当前的结构中,“主”包称为src,因为这是您的顶级__init__.py 所在的位置。可能不是你想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2019-10-14
      • 2019-12-08
      相关资源
      最近更新 更多