新手向——用python編寫(xiě)命令行應(yīng)用的簡(jiǎn)潔方式

The easy (and nice) way to do CLI apps in Python——github源碼 為一個(gè)簡(jiǎn)單的python命令行應(yīng)用的基本結(jié)構(gòu)。

我們有一些方法可以做出Python命令行式app。我試過(guò)它們,不過(guò)它們大都有自己的痛點(diǎn)和煩惱。所以我到社區(qū)里去尋找一種更好的方法。

什么是CLI?

CLI 意味著命令行界面(command line interface)。它是一類(lèi)用命令行/終端調(diào)用的app。作為開(kāi)發(fā)人員,更是一個(gè)少用鼠標(biāo),多用鍵盤(pán)黨,我一直使用CLI應(yīng)用。當(dāng)我需要一些為自己服務(wù)的定制軟件時(shí),CLI就能滿足我的需求,而python是一門(mén)能夠快速生產(chǎn)CLI應(yīng)用的偉大語(yǔ)言。

文件系統(tǒng)結(jié)構(gòu)

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

正如你所見(jiàn),該項(xiàng)目的根目錄被我命名為pycli。該應(yīng)用也將在setup.py中被設(shè)置為以名稱(chēng)pycli被調(diào)用。

CLI子目錄

在該CLI根目錄下只有一個(gè)子目錄。它的名字和CLI應(yīng)用同名,但是在更復(fù)雜的CLI應(yīng)用中,你需要有多個(gè)包。每個(gè)子目錄是每個(gè)包的容器。在我的簡(jiǎn)單案例中,只有單個(gè)包,也就是單個(gè)子目錄。

__init__.py

這個(gè)文件(文件)放在這里是告訴Python這個(gè)目錄是一個(gè)包。它可以是空的,只是做個(gè)關(guān)于包的簡(jiǎn)單提示;也可以包含實(shí)際代碼,在包自身初始化時(shí)會(huì)被運(yùn)行。

__main__.py

這是重要部分,是我們CLI應(yīng)用的入口,根目錄下的setup.py中的安裝配置會(huì)指示它。這里只是放些簡(jiǎn)單的代碼在這里表明它起作用了。

import sys
from .classmodule import MyClass
from .funcmodule import my_function
def main(): 
# 以下內(nèi)容中的參數(shù)解析方式并不好,這里只是為了簡(jiǎn)單
# 最好使用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()
#以下無(wú)關(guān)于包安裝,只是為了本文件的測(cè)試
if __name__ == '__main__':
    main()

上面所做的只是引入一些其它模塊,分析被傳入CLI的命令行參數(shù),然后使用導(dǎo)入模塊的成員(一個(gè)簡(jiǎn)單的函數(shù)和一個(gè)簡(jiǎn)單的類(lèi))。

classmodule.py

一個(gè)被導(dǎo)入__main__.py并被實(shí)例化的極簡(jiǎn)的類(lèi)(也沒(méi)啥用)。這里是為了說(shuō)明如何從同一個(gè)包里的其它模塊中引入一個(gè)類(lèi)

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定義一個(gè)可以導(dǎo)入的類(lèi),funcmodule.py展示了如何定義一個(gè)簡(jiǎn)單的函數(shù)讓__main__.py導(dǎo)入并調(diào)用。

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

setup.py

現(xiàn)在讓我們回到CLI源碼的根目錄。setup.py文件將所有東西聯(lián)系在一起并告訴Python如何處理它們。

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

第一眼看上去可能覺(jué)得很復(fù)雜。但是全部工作只是從setuptools庫(kù)導(dǎo)入setup函數(shù),并傳入一些參數(shù)來(lái)調(diào)用它。其中大部分是不言自明的。packages參數(shù)是根目錄下所有包的列表。
entry_points是重要部分。它用字符串表明當(dāng)前應(yīng)用該以什么名稱(chēng)被調(diào)用,以及被運(yùn)行時(shí)真正調(diào)用的是什么。這里寫(xiě)的是pycli = pycli.__main__:main,也就是說(shuō),該應(yīng)用被叫做pycli,當(dāng)執(zhí)行該應(yīng)用時(shí)它會(huì)調(diào)用pycli包下的__main__模塊的main函數(shù)。就是這樣!

install.sh

安裝你的Python CLI應(yīng)用的最佳方式是使用pip(python3則是pip3)。在CLI源碼的根目錄下運(yùn)行pip3 install . 將會(huì)使用setup.py作為"指令"安裝這個(gè)應(yīng)用,同樣,使用pip3 uninstall pycli會(huì)卸載這個(gè)應(yīng)用。

寫(xiě)在腳本中即是

pip3 uninstall pycli -y  # 標(biāo)簽-y意味著確認(rèn)卸載
pip3 install .

這樣會(huì)安裝到python Lib的site-packages中,或者更簡(jiǎn)潔的是

pip3 install -e .

這樣是在當(dāng)前根目錄下生成了egg-info文件,而在site-packages文件夾中生成一個(gè)egg-link鏈接,如下圖


這樣,就可以直接運(yùn)行install.sh以現(xiàn)有的CLI源碼來(lái)更新原來(lái)的CLI應(yīng)用了。

總結(jié)

掌握了簡(jiǎn)單的流程,用python編寫(xiě)命令行程序是簡(jiǎn)潔高效的。使用結(jié)果如首圖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容