我在一个文件app_name.py
中编写了一个命令行应用程序,它可以正常工作。现在,我将其分为不同的.py文件,以简化管理和可读性。我将所有这些py文件放置在src/
文件夹中,因为我在github上看到了很多。
app_name/
src/
file1.py
file2.py
cli.py
__init__.py
我已将所有导入都放置在
__init__.py
中。相对的导入(例如from .file1 import function1
)不在__init__
中,而是放置在需要的单个文件中。例如,#!usr/bin/env python
#__init__.py
import os
import argparse
#etc...
run_cli()
在cli.py中,我有
from .file1 import function1
def run_cli(): pass
if __name__ == '__main__':
run_cli()
这是因为当我在实际命令行上使用
app_name <arguments>
时,__name__
不是main,因此我在run_cli()
中调用__init__.py
。虽然这看起来不太正确,但我将不得不调用src
而不是app_name
最佳答案
我认为您可能会混淆两件事。在您的源代码发行版中有一个src
目录是一件相当普遍且惯用的事情。在已安装的程序包或应用程序中包含的内容就不多了
有两种基本的结构方式。
首先,您可以构建一个Python发行版,将软件包安装到站点软件包中,然后将脚本安装到PATH上Python脚本所在的任何位置。 Python Packaging User Guide在其有关构建和分发软件包的教程中对此进行了介绍。请参见Layout和Scripts部分,以及从那里链接的示例。
通常,这会为您提供一个已安装的布局,如下所示:
<...somewhere system/user/venv .../lib/pythonX.Y/site-packages>
app_name/
file1.py
file2.py
cli.py
__init__.py
<...somewhere.../bin/>
app_name
但是,取决于用户选择安装东西的方式,它可以是鸡蛋, zipper 包,轮子或其他任何东西。只要您的代码有效,您就不必在意。特别是,您的代码可以假定
app_name
是可导入的程序包。理想情况下,路径上的
app_name
脚本是一个“入口点”脚本(pip
本身可能是您系统上的一个很好的示例),理想情况下,它是在安装时即时生成的。使用setuptools
,您只需指定应导入哪个软件包以及应在该软件包中调用哪个函数,它将完成其他所有工作-确保在安装时释放实际使用的Python,弄清楚如何对软件包进行pkg_resources
并添加将其添加到sys.path
(默认情况下不需要,但是如果您不希望将其导入,则可以使其工作),依此类推。如原始提问者的评论中所述,python-commandline-bootstrap可能会帮助您更快地组合此解决方案。
替代方法是将所有内容都保留在网站程序包之外,并使程序包特定于您的应用程序。在这种情况下,您基本上想做的是:
dirname(abspath(argv[0]))
添加到sys.path
之前的import
之前。 PATH
上的某个位置。 在这种情况下,您必须手动编写包装脚本,但是这样就不需要任何花哨的东西了。
但是通常,您实际上并不希望应用程序依赖于用户是否拥有某些特定的Python版本和设置。您可能想要使用
pyInstaller
,py2exe
,py2app
,cx_Freeze
,zc.buildout
等工具来完成以上所有工作。它们都做不同的事情,一直到用自定义,独立的,剥离的Python框架和stdlib以及嵌入该框架的包装可执行文件来构建Mac .app
捆绑目录。无论哪种方式,您实际上都不想调用包目录
src
。这意味着程序包本身将被命名为src
,这不是一个好名字。如果您的应用程序名为spamifier
,那么您想在回溯中看到spamifier
,而不是src
,对吗?
关于python - 如何构建一个基于命令行的简单python项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26556795/