从子文件夹导入模块


104

我想将子文件夹作为模块导入。因此,每个子文件夹都包含一个__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

Answers:


136

无需与您PYTHONPATHsys.path此处混淆。

为了在包中正确使用绝对导入,还应该包括“ root”包名,例如:

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

或者您可以使用相对导入

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

47
要记住的一件事!添加__init__.py到要从中导入的每个子文件夹。
阿齐兹·阿尔托

6
__init__.py可能会完成这项工作。
cerebrou

1
如果以前Foo1在父目录中并且编码为,则语法将是什么from Foo1 import *。有没有一种方法可以达到相同的效果,因此您不必在所有内容前加上前缀Foo1
jxramos

1
@AzizAlto:未经您的评论,此解决方案不是很有用
Alex

21

只是在这里通知。(来自新蜜蜂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文件,插入环境路径,非常担心出了什么问题……

在很长很长一段时间后,我在和我的一个朋友交谈时想出了这一点。使用这样的命名约定我并不傻。我绝对不要使用空格或特殊符号为任何文件夹或文件定义名称。所以,这就是我想传达的。祝你有美好的一天!

(很抱歉在此发布大量文章……只是让我的挫败感....::)谢谢!)


22
空格和破折号(“-”)可能会导致这种情况,但是下划线(“ _”)仍然可以正常工作。
cowlinator '17

6

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

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

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

2

假设您的项目采用以下结构:

+---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)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.