python - 运行 python 应用程序并从目录中的不同路径导入模块

标签 python python-2.7 docker path docker-compose

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

  • 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 -epack 中的任何内容制作虚拟环境的源代码成为您实际的本地源代码树。如果 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/

    相关文章:

    python-2.7 - 用于频率计数的意大利句子词形化

    python - 使用pip安装python包报错

    apache - 同一个 docker 容器上的多个虚拟主机

    docker - 要在jenkins上进行dockerize构建,需要哪些插件或预安装?

    javascript - 如何隐藏一行表(或列表项)并更新数据存储而不重新加载页面?

    python - 扩展一个看起来像 : "1-3,6,8-10" to [1, 2,3, 6, 8,9,10 的范围]

    python - "with"可以用作Python中的标识符吗?

    docker - 更新注册表中的 docker 镜像

    python - 在Python中绘制贝塞尔曲线的问题

    Python加入more_itertools.windowed结果