(TL; DR)我正在创建一个Python程序包,在导入和理解python如何在程序包/模块中运行脚本时总是遇到麻烦。如何正确地在目录之间导入以下目录结构?我应该将要用作该应用程序入口点的脚本放在哪里,用户应该如何运行它?
我当前的目录结构如下:
package_name
├── (venv)
├── __init__.py
├── package_name
│ ├── __init__.py
│ ├── script.py
│ ├── common
│ │ ├── __init__.py
│ │ ├── cfg1.py
│ │ └── cfg2.py
│ ├── core
│ │ ├── __init__.py
│ │ ├── utils1.py
│ │ └── utils2.py
│ └── templates
│ ├── base.txt
│ ├── template1.txt
│ ├── template2.txt
│ ├── ...
│ ├── templateN.txt
├── setup.py
└── tests
└── test_core
├── data
└── test_core.py
在script.py
内部:
from core import utils1, utils2
def main():
# Parse some args - want the user to supply them from command line
utils1.thing()
utils2.another_thing()
if __name__ == "__main__":
main()
在utils1.py
内部:
from package_name.common.cfg1 import allowed_configs
# This fails
# And then the utilities are here
我希望用户能够调用script.py并提供命令行参数来执行某些操作。当我跑步时:
python3 pathto/package_name/package_name/script.py option1 --arg1 value
激活我的virtualenv后,从命令行收到utils1.py
的错误消息:
ModuleNotFoundError: No module named 'package_name.common'
如果我将其作为模块运行:
python3 -m package_name.package_name.script option1 --arg1 value
我在这条线上收到另一个错误:
from core import utils1, utils2
错误:
ModuleNotFoundError: No module named 'core'
现在,根据我对模块/软件包/脚本的研究,我知道如果不使用-m
标志,就无法将软件包中的模块作为脚本运行。我认为我会收到该错误是有道理的,但我不直观地理解原因。
我真的不想手动弄乱Python路径,但是我可以在以下方面使用一些建议:
1)此类Python软件包的正确结构/布局旨在分发给用户并从命令行调用?最终用户应如何最终调用script.py
?
2)如何在子目录之间导入而不在脚本中手动设置路径?有可能吗?
3)我还没有用setup.py“安装”该软件包,因为我还没有弄清楚它是如何工作的。是否可以解决我的setup.py以使packages=find_packages()
解决此问题?如果是这样,我每次要测试对代码的更改时是否都需要运行setup.py development
?
答案 0 :(得分:0)
我能够通过以下方式使其工作:
我希望能够从命令行运行脚本,因此我跟随着此页面,以了解如何在setup.py中实现入口点:https://click.palletsprojects.com/en/5.x/setuptools/
我尝试添加一个scripts
关键字,但是我不太清楚如何使它起作用。通过使用console_scripts
,我在用pip install -e .
安装脚本之后就可以像可执行文件一样直接调用脚本。对于其他有相同问题的人,请注意,当我使用pip安装此文件时,我是从保存setup.py的目录中进行安装的(事后看来,但我尝试从顶层package_name目录上方进行首次安装)
以下更改了我的导入内容。最初,我有from core import utils1, utils2
,但是当我使用pip安装软件包时,它更改为package_name.core
(因为package_name是软件包)。其他失败的导入路径也有错误。正确的导入为package_name.common.cfg1
希望这对某人有帮助!我认为有用的参考文献: