python - 如何构建一个基于命令行的简单python项目

标签 python

我在一个文件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在其有关构建和分发软件包的教程中对此进行了介绍。请参见LayoutScripts部分,以及从那里链接的示例。

通常,这会为您提供一个已安装的布局,如下所示:

<...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版本和设置。您可能想要使用pyInstallerpy2exepy2appcx_Freezezc.buildout等工具来完成以上所有工作。它们都做不同的事情,一直到用自定义,独立的,剥离的Python框架和stdlib以及嵌入该框架的包装可执行文件来构建Mac .app捆绑目录。

    无论哪种方式,您实际上都不想调用包目录src。这意味着程序包本身将被命名为src,这不是一个好名字。如果您的应用程序名为spamifier,那么您想在回溯中看到spamifier,而不是src,对吗?

    关于python - 如何构建一个基于命令行的简单python项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26556795/

    相关文章:

    python - Linux 上 Python 中的随机数生成器

    python - 给定经纬度列表,如何在球体上绘制热图?

    python - Drive-SDK Python 代码无法通过选定的标题词获取驱动文件

    python - 在 OpenERP-7 中通过按钮调用 TreeView

    python - 如何让这个过程更快?

    python - 使用 Python 将数组中的负值替换为 0 并将大于 1 的值替换为 1 的最快方法是什么?

    python - python正则表达式中*和+的区别?

    python - 无法访问传递给 NASM 64 位 DLL 的数组指针

    python - 将列表转换为字典时的速度问题

    python - iruby notebook 只运行 python