我有一个python项目,其层次结构类似于:(但src下有更多文件夹(
ip-rep/
│
├── ip_rep/
│ ├── __init__.py
│ ├── run.py
│ ├── src/
│ ├── __init__.py
│ ├── cli_tool/
│ ├── __init__.py
│ ├---- cli_loader.py
├── tests/
│ ├── test_cli_loader
│ ├── test_cli_loader.py
│
├── dockefile
├── bash_start.sh
现在在dockerfile中,我有这样的东西(简化(:
RUN mkdir app
WORKDIR /app
ADD ip_rep /app/ip_rep
ADD load_ips.sh /app/
RUN chmod +x /app/load_ips.sh
ENTRYPOINT ["/bin/bash", "load_ips.sh"]
这就是bash文件(再次简化(:
python ip_rep/run.py
这是run.py文件中导入的一个示例:
from ip_rep.src.cli_tool.cli_loader import CliTool
当我试图运行它时,我得到了错误:
Traceback (most recent call last):
File "ip_rep/run.py", line 9, in <module>
from ip_rep.src.cli_tool.cli_loader import CliTool
ModuleNotFoundError: No module named 'ip_rep'
我真的不明白我做错了什么。我不能删除run.py中的ip_rep,只做src.
文件,因为这样测试就停止了。
我错过了什么?
使用此结构代替
ip-rep/
│
├── ip_rep/
│ ├── __init__.py
│ ├── cli_tool/
│ ├── __init__.py
│ ├---- cli_loader.py
├── scripts/
│ ├── run.py
│
├── tests/
│ ├── test_cli_loader
│ ├── test_cli_loader.py
│
├── dockerfile
├── bash_start.sh
(您可以忽略${SOMEDIR}/
部分,但需要它作为下面的示例。(
将run.py
移动到与ip_rep
包目录处于同一级别的单独目录中,但不在其中;类似于测试。
它还删除了不必要的src/
目录,正如Lenormju所评论的那样。
您的run.py
文件现在应该具有导入行:
from ip_rep.cli_tool.cli_loader import CliTool
你的bash_start.sh
应该(至少(有类似的东西
PYTHONPATH=app/ip_rep
python app/ip_rep/scripts/run.py
如果bash脚本已经在app/ip_rep
目录中,那么您不需要设置PYTHONPATH
的可能性也不大:Python会自动将当前目录放在其搜索路径上。然后脚本也可以是相对的,整个事情就变成了
python scripts/run.py
第一个变体更明确,并允许将bash脚本放在其他地方。
当然,最好的部分是正确安装包和脚本,使它们位于系统PATH和PYTHONPATH上。这将需要运行类似pip install .
的内容,并为项目提供有效的setup.py
或pyproject.toml
文件。这样,bash脚本就变成了简单的run.py
(只有那一行(,甚至run
,这取决于您如何配置。当然;运行";对于脚本来说,这是一个通用的坏名字,但这应该是您可以努力的方向。