在python中导入[重复]

Posted

技术标签:

【中文标题】在python中导入[重复]【英文标题】:Import in python [duplicate] 【发布时间】:2017-04-01 08:52:07 【问题描述】:

我阅读了很多与我提出的问题相关的答案,但我仍然不明白如何使我正在尝试的这件事成为可能。 所以让我们进入正题。我将报告我的应用程序的简化版本。

假设我有一个名为 project主文件夹,其中有一个 src 主包,其中包含 三个子包:

clustering(包含一个文件:clustering.pyparser(包含一个文件:parser.pysupport_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.pyclustering.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

ma​​in.py

from support_class.support  import Support

那么,python clustering.pypython 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。它不会作为任何包的一部分加载,因此它不能进行相对导入。执行此操作的正确方法是创建一个单独的脚本,该脚本仅用作主脚本,而不使用任何模块脚本作为主脚本。例如,创建这样的脚本

ma​​in.py

from parser import parser
parser.main()

然后你可以运行python /path/to/main.py,它会工作。

另外,请注意您的包装布局。在您的示例中,parserclusteringsupport_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 文件 [重复]

我啥时候使用 ,啥时候不在 JavaScript 中导入 [重复]

在android Studio中导入.aar [重复]

在maven项目中导入外部jar而不创建依赖项[重复]