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