作为引用,我查看了以下链接。
我知道我的做法是错误的,我试图通过
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/