从子文件夹导入模块

Posted

技术标签:

【中文标题】从子文件夹导入模块【英文标题】: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

【问题讨论】:

【参考方案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 之类的错误

尝试了许多搜索并查看了许多 *** 问题,但无法确定出了什么问题。我多次交叉检查了我的文件,我使用了__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

【讨论】:

以上是关于从子文件夹导入模块的主要内容,如果未能解决你的问题,请参考以下文章

如何从子模块导入python脚本?

使用 kotlin-android-extensions 从子模块导入视图时未解析的引用

在 Python 中,如何从导入的模块访问主模块的命名空间?

从子目录导入文件?

QML 从子目录导入样式文件

python aes模块怎么导入