[英]Running python application and importing module from a different path within directory
作為參考,我查看了以下鏈接。
我知道我在做錯了,我試圖避免相對路徑,並盡可能通過sys.path
更改,盡管如果這是我唯一的選擇,請幫助我提出解決方案。
注意,這是我當前工作目錄結構的示例。 我想我應該再添加一些背景信息。 我開始將__init__.py
添加到每個目錄中,以便將它們視為軟件包和子軟件包,但是我不確定那是我真正想要的。
myapp/
pack/
__init__.py
helper.py
runservice/
service1/
Dockerfile
service2/
install.py
Dockerfile
我將要調用的唯一軟件包位於pack/
目錄中,因此我認為這應該是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打包用戶指南》中有一個關於打包和分發項目的部分 ,該部分最為相關。 盡管您對將結果上傳到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 .)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.