在python中导入[重复]
Posted
技术标签:
【中文标题】在python中导入[重复]【英文标题】:Import in python [duplicate] 【发布时间】:2017-04-01 08:52:07 【问题描述】:我阅读了很多与我提出的问题相关的答案,但我仍然不明白如何使我正在尝试的这件事成为可能。 所以让我们进入正题。我将报告我的应用程序的简化版本。
假设我有一个名为 project 的 主文件夹,其中有一个 src 主包,其中包含 三个子包:
clustering(包含一个文件:clustering.py) parser(包含一个文件:parser.py) support_class(包含一个文件:myClass.py)每个文件夹中,除了项目一个,都有一个__init__.py
现在,集群和解析器包中包含的 python 脚本应该同时使用 support_class 中包含的 myclass.py。
我尝试了相对导入,但它们不起作用,因为我想直接运行集群和解析器包中包含的脚本,并且不想使用 -m 选项。
Es。 python parser.py [参数]
我使用的相对导入示例是:
from ..supportClass import myClass
我试图将包路径添加到 sys.path 但有些东西不起作用,因为它仍然告诉我它找不到模块。
Es。
sys.path.insert(0, "~/project/src")
from support_class import myClass.py
谁能建议在 python 2.7 中执行此操作的最佳方法? 如果我可以避免使用 sys.path 选项,那就太好了,因为我不太喜欢这个解决方案。
提前致谢。
【问题讨论】:
您能告诉我们您是如何尝试使用相对路径的吗? 我尝试过,例如在 parser.py 中,执行以下操作:from ..support_class import myClass.py 您是直接从其子文件夹运行parser.py
,还是从您的***文件夹导入它?编辑:我的错,再次阅读您的问题,您已经提供了该信息。
我正在从 parser 文件夹运行 parser.py 并尝试从 parser.py 导入 myClass.py 编辑:不用担心 :)
包的设计不是为了让嵌套在其中的子包模块作为主包运行。要使sys.path.insert(0, "~/project/src")
工作,请尝试在第二个参数上使用os.path.expanduser()
,然后再将其传递给insert()
方法。
【参考方案1】:
让我们从您项目的文件夹架构开始:
MyProject/
└── src
├── clustering
│ ├── __init__.py
│ └── clustering.py
├── parser
│ ├── __init__.py
│ └── parser.py
├── support_class
│ ├── __init__.py
│ └── support.py
└── main.py
如果我没记错的话,您的问题是您想从parser.py
和clustering.py
中导入support.py
,并在需要时能够独立运行这两个。给你两个字:
条件导入
(还有一个,在找到真正的其他解决方案后;):PYTHONPATH
)
假设您的脚本有一个 if __name__ == "__main__":
部分来运行您的测试,您可以简单地将以下内容作为它们的导入:
clustering.py & parser.py:
if __name__ == "__main__":
import sys
import os
PACKAGE_PARENT = '..'
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))
from support_class.support import Support
else:
from support_class.support import Support
main.py:
from support_class.support import Support
那么,python clustering.py
和 python parser.py to your heart's content!
这使得它与 https://***.com/a/16985066/3425488 重复
【讨论】:
【参考方案2】:首先,您必须在您拥有实际包的目录中创建一个 __init __.py(两个 =“_”,前后,无空格)文件。
其次,您只想从要导入的 python 脚本中调用您的包。
例如:
my_script.py #你想要包含/导入你的包的脚本
-
my_clustering_dir # 包含软件包文件的目录
my_clustering.py # 文件应该在 my_clustering_dir 中
"__init __".py # 确保此文件仅在 my_clustering_dir 中(可以为空)
现在,您可以访问 my_script.py。然后,您可以添加以下内容:
from my_clustering_dir import my_clustering #no extension (.py) needed
【讨论】:
【参考方案3】:当你像这样调用 python 脚本时
python parser.py
该模块加载为__main__
,而不是parser.parser
。它不会作为任何包的一部分加载,因此它不能进行相对导入。执行此操作的正确方法是创建一个单独的脚本,该脚本仅用作主脚本,而不使用任何模块脚本作为主脚本。例如,创建这样的脚本
main.py
from parser import parser
parser.main()
然后你可以运行python /path/to/main.py
,它会工作。
另外,请注意您的包装布局。在您的示例中,parser
和 clustering
和 support_class
不是子包,它们是***包。通常,如果您有一个名为 project
的包并且您使用的是 src
目录,那么您的布局将如下所示:
/project
setup.py
/src
/project
__init__.py
/clustering
__init__.py
/parser
..
或者,如果您使用setup.py
脚本构建实际的python 包,您可以使用setuptools
中的console_scripts
入口点自动生成脚本。
setup(
...
entry_points =
'console_scripts': ['myparser=project.parser:main'],
...
)
【讨论】:
以上是关于在python中导入[重复]的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 中导入 Tkinter 时出现 ImportError [重复]
在 Node.js 中导入:错误“必须使用导入来加载 ES 模块”[重复]
在 phpMyadmin 中导入大型 SQL 文件 [重复]