【问题标题】:Import module from subfolder从子文件夹导入模块
【发布时间】:2012-02-15 18:03:32
【问题描述】:

我想将子文件夹作为模块导入。因此每个子文件夹都包含一个__init__.py。我的文件夹结构是这样的:

src\
  main.py
  dirFoo\
    __init__.py
    foofactory.py
    dirFoo1\
      __init__.py
      foo1.py
    dirFoo2\
      __init__.py
      foo2.py

在我的主脚本中我导入

from dirFoo.foofactory import FooFactory

在这个工厂文件中,我包含了子模块:

from dirFoo1.foo1 import Foo1
from dirFoo2.foo2 import Foo2

如果我调用我的 foofactory,我会收到错误消息,即 python 无法导入子模块 foo1 和 foo2:

Traceback (most recent call last):
  File "/Users/tmp/src/main.py", line 1, in <module>
from dirFoo.foofactory import FooFactory
  File "/Users/tmp/src/dirFoo/foofactory.py", line 1, in    <module>
from dirFoo1.foo1 import Foo1
    ImportError: No module named dirFoo1.foo1

【问题讨论】:

    标签: python import module subdirectory


    【解决方案1】:

    这里没有必要乱用你的PYTHONPATHsys.path

    要在包中正确使用绝对导入,您还应该包含“根”包名,例如:

    from dirFoo.dirFoo1.foo1 import Foo1
    from dirFoo.dirFoo2.foo2 import Foo2
    

    或者你可以使用relative imports:

    from .dirfoo1.foo1 import Foo1
    from .dirfoo2.foo2 import Foo2
    

    【讨论】:

    • 要记住的一件事!将__init__.py 添加到您要从中导入的每个子文件夹中。
    • Empty __init__.py 可以完成这项工作。
    • 如果之前的 Foo1 位于父目录中并且编码为 from Foo1 import * 之类的代码,那么语法会是什么。有没有办法达到同样的效果,这样你就不必在所有东西前面加上Foo1
    • @AzizAlto:没有您的评论,这个解决方案不是很有用
    • 使用from .dirfoo1.foo1 import Foo1 等对我有用。此外,我有这两行,而不是空的 dunder 初始化文件:import site 后跟 site.addsitedir('./')
    【解决方案2】:

    只是在这里通知。 (来自新手,keviv22)

    永远不要为了您自己的利益而使用“-”或“_”等符号命名文件夹或文件。如果你这样做了,你可能会遇到一些问题。就像我的一样,虽然您的导入命令是正确的,但您将无法成功导入此类命名文件夹中可用的所需文件。

    无效的文件夹命名如下:

    • 通用类文件夹
    • Generic_Classes_Folder

    以上的有效文件夹命名:

    • GenericClassesFolder 或 Genericclassesfolder 或 genericClassesFolder(或像这样,单词之间没有任何空格或特殊符号)

    我犯了什么错误:

    考虑文件结构。

    Parent
       . __init__.py
       . Setup
         .. __init__.py
         .. Generic-Class-Folder
            ... __init__.py
            ... targetClass.py
       . Check
         .. __init__.py
         .. testFile.py
    

    我想做什么?

    • 从 testFile.py,我想在 Generic-Class-Folder 文件中导入 'targetClass.py' 文件,以使用 'targetClass.py' 文件中名为“functionExecute”的函数

    我做了什么命令?

    • 来自“testFile.py”,写入命令, from Core.Generic-Class-Folder.targetClass import functionExecute
    • 出现SyntaxError: invalid syntax 之类的错误

    尝试了许多搜索并查看了许多 stackoverflow 问题,但无法确定出了什么问题。我多次交叉检查了我的文件,我使用了__init__.py 文件,插入了环境路径,非常担心出了什么问题......

    在很长很长时间之后,我在和我的一个朋友交谈时发现了这一点。使用这样的命名约定我有点愚蠢。我不应该使用空格或特殊符号来定义任何文件夹或文件的名称。所以,这就是我想要传达的。祝你有美好的一天!

    (很抱歉关于这个的巨大帖子......只是让我的挫败感消失...... :) 谢谢!)

    【讨论】:

    • 空格和破折号 ("-") 会导致这种情况,但下划线 ("_") 应该仍然可以正常工作。
    【解决方案3】:

    设置您的 PYTHONPATH 环境变量。例如像这样的 PYTHONPATH=.:..(对于 *nix 系列)。

    您还可以手动将当前目录(在您的情况下为 src)添加到 pythonpath:

    import os
    import sys
    sys.path.insert(0, os.getcwd())
    

    【讨论】:

      【解决方案4】:

      假设你的项目是这样组织的:

      +---MyPythonProject
      |   +---.gitignore
      |   +---run.py
      |   |   +---subscripts
      |   |   |   +---script_one.py
      |   |   |   +---script_two.py
      

      run.py 中,您可以通过以下方式导入脚本一和二:

      from subscripts import script_one as One
      from subscripts import script_two as Two
      

      现在,仍然在 run.py 内部,您将能够调用他们的方法:

      One.method_from_one(param)
      Two.method_from_two(other_param)
      

      【讨论】:

        【解决方案5】:

        只需创建一个空的__init__.py 文件并将其添加到根目录以及您拥有其他python 模块的python 应用程序的所有子目录/文件夹中。见https://docs.python.org/3/tutorial/modules.html#packages

        【讨论】:

          猜你喜欢
          • 2012-12-13
          • 2017-06-07
          • 2013-01-18
          • 2013-08-26
          • 2019-09-16
          相关资源
          最近更新 更多