美文网首页Python实践Pythoner集中营程序员
新手向——用python编写命令行应用的简洁方式

新手向——用python编写命令行应用的简洁方式

作者: treelake | 来源:发表于2016-10-28 16:08 被阅读2310次

    The easy (and nice) way to do CLI apps in Python——github源码 为一个简单的python命令行应用的基本结构。

    我们有一些方法可以做出Python命令行式app。我试过它们,不过它们大都有自己的痛点和烦恼。所以我到社区里去寻找一种更好的方法。

    什么是CLI?

    CLI 意味着命令行界面(command line interface)。它是一类用命令行/终端调用的app。作为开发人员,更是一个少用鼠标,多用键盘党,我一直使用CLI应用。当我需要一些为自己服务的定制软件时,CLI就能满足我的需求,而python是一门能够快速生产CLI应用的伟大语言。

    文件系统结构

    pycli/
    ├── README.md
    ├── install.sh
    ├── pycli
      ├── __init__.py
      ├── __main__.py
      ├── classmodule.py
      └── funcmodule.py
    └── setup.py
    

    正如你所见,该项目的根目录被我命名为pycli。该应用也将在setup.py中被设置为以名称pycli被调用。

    CLI子目录

    在该CLI根目录下只有一个子目录。它的名字和CLI应用同名,但是在更复杂的CLI应用中,你需要有多个包。每个子目录是每个包的容器。在我的简单案例中,只有单个包,也就是单个子目录。

    __init__.py

    这个文件(文件)放在这里是告诉Python这个目录是一个包。它可以是空的,只是做个关于包的简单提示;也可以包含实际代码,在包自身初始化时会被运行

    __main__.py

    这是重要部分,是我们CLI应用的入口,根目录下的setup.py中的安装配置会指示它。这里只是放些简单的代码在这里表明它起作用了。

    import sys
    from .classmodule import MyClass
    from .funcmodule import my_function
    def main(): 
    # 以下内容中的参数解析方式并不好,这里只是为了简单
    # 最好使用argparse或者click模块做这方面的工具
        print('in main')
        args = sys.argv[1:]
        print('count of args :: {}'.format(len(args)))
        for arg in args:
            print('passed argument :: {}'.format(arg))
        my_function('hello world')
        my_object = MyClass('Thomas')
        my_object.say_name()
    #以下无关于包安装,只是为了本文件的测试
    if __name__ == '__main__':
        main()
    

    上面所做的只是引入一些其它模块,分析被传入CLI的命令行参数,然后使用导入模块的成员(一个简单的函数和一个简单的类)。

    classmodule.py

    一个被导入__main__.py并被实例化的极简的类(也没啥用)。这里是为了说明如何从同一个包里的其它模块中引入一个类

    class MyClass():
        def __init__(self, name):
            self.name = name
        def say_name(self):
            print('name is {}'.format(self.name))
    

    funcmodule.py

    classmodule.py展示如何为__main__.py定义一个可以导入的类,funcmodule.py展示了如何定义一个简单的函数让__main__.py导入并调用

    def my_function(text_to_display):
        print('text from my_function :: {}'.format(text_to_display))
    

    setup.py

    现在让我们回到CLI源码的根目录。setup.py文件将所有东西联系在一起并告诉Python如何处理它们

    from setuptools import setup
    setup(
        name = 'pycli',
        version = '0.1.0',
        packages = ['pycli'],
        entry_points = {
            'console_scripts': [
                'pycli = pycli.__main__:main'
            ]
        })
    

    第一眼看上去可能觉得很复杂。但是全部工作只是从setuptools库导入setup函数,并传入一些参数来调用它。其中大部分是不言自明的。packages参数是根目录下所有包的列表。
    entry_points是重要部分。它用字符串表明当前应用该以什么名称被调用,以及被运行时真正调用的是什么。这里写的是pycli = pycli.__main__:main,也就是说,该应用被叫做pycli,当执行该应用时它会调用pycli包下的__main__模块的main函数。就是这样!

    install.sh

    安装你的Python CLI应用的最佳方式是使用pip(python3则是pip3)。在CLI源码的根目录下运行pip3 install . 将会使用setup.py作为"指令"安装这个应用,同样,使用pip3 uninstall pycli卸载这个应用。

    写在脚本中即是

    pip3 uninstall pycli -y  # 标签-y意味着确认卸载
    pip3 install .
    

    这样会安装到python Lib的site-packages中,或者更简洁的是

    pip3 install -e .
    

    这样是在当前根目录下生成了egg-info文件,而在site-packages文件夹中生成一个egg-link链接,如下图


    这样,就可以直接运行install.sh以现有的CLI源码来更新原来的CLI应用了。

    总结

    掌握了简单的流程,用python编写命令行程序是简洁高效的。使用结果如首图

    相关文章

      网友评论

      • casaba:最近怎么开始写新手文了啊
        casaba:@treelake 可以的,是时候出来创业了
        treelake: @casaba 为编程教育考虑啊

      本文标题:新手向——用python编写命令行应用的简洁方式

      本文链接:https://www.haomeiwen.com/subject/moheuttx.html