从子文件夹导入模块
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】:这里没有必要乱用你的PYTHONPATH
或sys.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
【讨论】:
以上是关于从子文件夹导入模块的主要内容,如果未能解决你的问题,请参考以下文章
使用 kotlin-android-extensions 从子模块导入视图时未解析的引用