【问题标题】:Why can't I import package from sibling directory in python even with use of __init__.py?为什么即使使用 __init__.py,我也不能从 python 中的同级目录导入包?
【发布时间】:2016-01-06 23:11:04
【问题描述】:

我有子文件夹 AB。我正在尝试从兄弟A 导入一个包。

我在每个子文件夹和根项目中都有__init__.py

然而,从我在文件夹 B 中执行的文件中,尽管文件存在于文件夹 A 中,但我收到以下错误:

Traceback (most recent call last):
  File "/home/ubuntu/workspace/cloud-devops/B/ufw_firewall.py", line 5, in <module>
    from getparms import *
ImportError: No module named getparms

如何导入我的包?

谢谢

【问题讨论】:

  • 我有点困惑。你能显示你的目录树以及每个目录中的文件吗?
  • from cloud-devops.A.getparams import * 有效吗?
  • 因为在某些时候您会想要将“cloud-develops”作为整个系统导入,所以您不希望在目录名称中包含 hiphen,因为它会导致 Python 包名称无效。

标签: python python-2.7


【解决方案1】:

使用相对导入 from ..A.getparms import * 或绝对导入 from cloud_devops.A.getparms import *

如果不从根开始或使用相对导入,您不能只从树叶的一个分支跳到另一个分支。

【讨论】:

  • 包名不能包含“-”——我把它改成了“_”以使 Python 有效。 (并建议 OP 重命名目录)。此外,如果您想改写自己,..A 中的点数是正确的。
  • @jsbueno:感谢您的修复。我很少使用相对导入语法,所以我很谨慎;限定符已删除。
【解决方案2】:

添加__init__.py 不会使模块可以从任何地方导入;它只是意味着该目录是一个包。您仍然需要在导入中使用包名称:

from A import getparms

(无论如何,请不要这样做from x import *。)

【讨论】:

    【解决方案3】:

    假设getparams 是一个模块,如果/home/ubuntu/workspace/ 在您的PYTHONPATH 中或通过例如添加site...

    import site
    site.addsitedir('/home/ubuntu/workspace/')
    

    ...您可以通过多种方式导入:

    from cloud_devops.A import getparams
    from cloud_devops.A import *
    

    请注意,您不能使用cloud-devops 作为模块名称,这就是我将其重命名为cloud_devops 的原因。在PEP 0008 中查看更多信息:

    包和模块名称

    模块应该有简短的全小写名称。如果提高可读性,可以在模块名称中使用下划线。 Python 包也应该有简短的全小写名称,但不鼓励使用下划线。

    ...或者您可以从B 中的脚本相对导入:

    from ..A import getparams
    from ..A import *
    

    两个点表示上一级包装。三个点向上两级,等等。

    但是,import * 被认为是不好的做法,因此请尽可能避免。为了可读性,我个人总是会做静态导入,而不是相对导入。

    【讨论】:

      猜你喜欢
      • 2021-11-08
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 2018-10-09
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多