【问题标题】:Import in python [duplicate]在python中导入[重复]
【发布时间】: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() 方法。

标签: python python-2.7 import relative-path absolute-path


【解决方案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

ma​​in.py:

from support_class.support  import Support

那么,python clustering.py 和 python parser.py to your heart's content!

这使得它与 https://stackoverflow.com/a/16985066/3425488 重复

【讨论】:

    【解决方案2】:

    首先,您必须在您拥有实际包的目录中创建一个 __init __.py(两个 =“_”,前后,无空格)文件。

    其次,您只想从要导入的 python 脚本中调用您的包。

    例如:

    my_script.py #你想要包含/导入你的包的脚本

    1. my_clustering_dir # 包含软件包文件的目录
    2. my_clustering.py # 文件应该在 my_clustering_dir 中
    3. "__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,它会工作。

      另外,请注意您的包装布局。在您的示例中,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'],
          }
          ...
      )
      

      【讨论】:

        猜你喜欢
        • 2019-08-19
        • 2012-06-07
        • 2016-07-07
        • 2011-11-13
        • 2013-06-26
        • 2013-12-24
        • 2015-10-19
        • 2016-10-19
        • 2012-06-07
        相关资源
        最近更新 更多