从子文件夹导入模块。

148

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

192

这里无需更改您的PYTHONPATHsys.path

为了在包中正确使用绝对导入,您应该同时包含“根”包名称,例如:

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

或者你可以使用相对导入

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

70
记住一件事!在你导入的每个子文件夹中都要添加 __init__.py 文件。 - Aziz Alto
11
空的 __init__.py 文件可能能够起到作用。 - cerebrou
2
如果之前Foo1在父目录中,而现在想要编写类似于from Foo1 import *的代码,语法应该怎么写呢?有没有一种方法可以实现相同的效果,而不必在每个变量前都加上Foo1前缀呢? - jxramos
1
@AzizAlto:没有你的评论,这个解决方案就不是很有用。 - Alex
使用 from .dirfoo1.foo1 import Foo1 等对我很有效。此外,我没有使用空的双下划线 init 文件,而是加入了这两行代码:import site 还有 site.addsitedir('./') - brethvoice
根据使用情况,Python 3.3+不再需要__init__.py(请参见https://dev59.com/71oU5IYBdhLWcg3wxIyA#37140173)。 - scai

31

仅仅是通知一下。(来自新手keviv22)

为了你的利益,请永远不要用"-"或者"_"等符号给文件夹或者文件命名。如果你这么做了,可能会遇到像我一样的问题,即使你的导入命令正确,你也无法成功导入所需的文件,因为它们位于这样命名的文件夹中。

以下是无效的文件夹命名:

  • Generic-Classes-Folder
  • 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"的函数。

我执行了什么命令?

  • 在'from testFile.py'中,我写下以下命令: from Core.Generic-Class-Folder.targetClass import functionExecute
  • 出现了类似于SyntaxError: invalid syntax的错误。

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

经过长时间的尝试,我在与朋友交谈时终于找到了原因。我有点傻,不能使用空格或特殊符号来定义文件夹或文件的名称。这就是我想传达的信息。祝你有愉快的一天!

(抱歉对此进行了如此长篇大论...只是让自己发泄一下.... :) 谢谢!)


37
空格和短横线(“-”)会导致这种情况,但下划线(“_”)仍然可以正常工作。 - cowlinator

11

设置PYTHONPATH环境变量。例如这样:PYTHONPATH=.:.. (对于*nix家族)。

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

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

7

假设你的项目结构如下:

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

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接