作为引用,我查看了以下链接。

  • Python Imports, Paths, Directories & Modules
  • Importing modules from parent folder
  • Importing modules from parent folder
  • Python Imports, Paths, Directories & Modules

  • 我知道我的做法是错误的,我试图通过 sys.path 尽可能避免相对路径和更改内容,但如果这些是我唯一的选择,请帮助我想出一个解决方案。

    请注意,这是我当前工作目录结构的示例。我想我应该添加更多的上下文。我开始将 __init__.py 添加到每个目录,因此它们将被视为包和子包,但我不确定这是否是我真正想要的。
    myapp/
        pack/
            __init__.py
            helper.py
        runservice/
            service1/
                 Dockerfile
            service2/
                install.py
                Dockerfile
    
    

    我将调用的唯一包存在于 pack/ 目录中,所以我相信这应该是唯一被 python 视为包的目录。

    接下来,这可能会变得有点棘手的原因,归根结底,这只是一个构建各种不同容器的服务。入口点将位于 python service*/install.py 中,我将 cd 放入脚本的工作目录中。这样做的原因是,我不希望 container1 (service1) 知道 service2 中的代码库,因为它与我想要的无关,并且代码要分开。

    但是,通过运行 install.py ,我需要能够做到: from pack.helper import function 但显然我做错了什么。

    有人可以帮我想出一个解决方案,这样我就可以将我的容器的入口点作为 cd service2 , python install.py

    另一个需要注意的重要事项,在脚本中我有如下逻辑:
    if not os.path.isdir(os.path.expanduser(tmpDir))
    

    我希望我们提出的任何解决方案都不会影响这里的逻辑?

    我为菜鸟问题道歉。

    编辑:

    注意,我想我可以做类似的事情
    sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
    

    但据我所知,这是不好的做法......

    最佳答案

    从根本上说,您所描述的是一个支持库,它与一组在其上运行的应用程序一起使用。它们碰巧在同一个存储库(“monorepo”)中,但这没关系。

    第一步是获取您的库并将其打包,就像普通的 Python 库一样。 Python Packaging User Guide 有一个关于 Packaging and distributing projects 的部分,主要是相关的;尽管您对将结果上传到 PyPI 并不是特别感兴趣。您至少需要那里描述的 setup.py 文件。

    通过这种重组,你应该能够做类似的事情

    $ ls pack
    pack/  setup.py
    $ ls pack/pack
    __init__.py  helper.py
    $ virtualenv vpy
    $ . vpy/bin/activate
    (vpy) $ pip install -e ./pack
    

    最后两行很重要:在您的开发环境中,他们创建了一个 Python 虚拟环境,一组独立的包,然后将您的本地库包安装到其中。仍然在那个虚拟环境中,您现在可以运行您的脚本
    (vpy) $ cd runservice/service2
    (vpy) $ ./install.py
    

    你的脚本不需要修改 sys.path ;您的库安装在“预期”的位置。

    您可以而且应该在这种环境中进行实时开发。 pip install -e 使 pack 中任何内容的虚拟环境的源代码成为您实际的本地源代码树。如果 service2 碰巧依赖于其他 Python 库,那么将它们列在 requirements.txt 文件中是一种很好的做法。

    一旦您将所有内容迁移到通常的 Python 打包方案中,就可以直接将其移植到 Docker 中。此处的 Docker 镜像与 Python 虚拟环境的作用大致相同,因为它具有独立的 Python 安装和独立的库树。所以一个 Dockerfile 可能或多或少看起来像

    FROM python:2.7
    
    # Copy and install the library
    WORKDIR /pack
    COPY pack/ ./
    RUN pip install .
    
    # Now copy and install the application
    WORKDIR /app
    COPY runservice/service2/ ./
    # RUN pip install -r requirements.txt
    
    # Set standard metadata to run the application
    CMD ["./install.py"]
    

    该 Dockerfile 取决于从组合存储库树的根运行
    sudo docker build -f runservice/service2/Dockerfile -t me/service2 .
    

    一种相关的高级技术是将其分解为单独的 Docker 镜像。一个包含基础 Python 和您安装的库,以及在此基础上构建的每个应用程序镜像。如果您需要构建所有应用程序,这可以避免多次重新安装库,但它也会导致具有多个 docker build 步骤的更复杂的序列。

    # pack/Dockerfile
    FROM python2.7
    WORKDIR /pack
    COPY ./ ./
    RUN pip install .
    

    # runservice/service2/Dockerfile
    FROM me/pack
    WORKDIR /app
    COPY runservice/service2/ ./
    CMD ["./install.py"]
    

    #!/bin/sh
    set -e
    (cd pack && docker build -t me/pack .)
    (cd runservice/service2 && docker build -t me/service2 .)
    

    关于python - 运行python应用程序并从目录中的不同路径导入模块,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57103830/

    10-12 17:02
    查看更多