上次寫的一個終端裡面鬥魚TV彈幕Python版本和Ruby版本,並且釋出到PIP和RubyGems上面.在釋出PIP包的時候,居然Google不到一篇可以非常好的講解這個流程的文章.於是整理這篇文章,並且方便後來自己檢索,並且方便他人找資料.
自推薦下依照本文定製的命令列工具danmu.fm的github地址:
https://github.com/twocucao/danmu.fm
本文的目的也是非常簡單:
寫一個Python命令列工具,並且釋出到PIP上面.並且在這個過程中給出我自己的一些思考.
如何分解這個釋出任務?
只需要進行如下的兩個步驟便可以:
- 1.寫好一個Python命令列工具.
- 2.釋出它.
當然,這樣不夠細緻.再細分一下.
- 1.寫好一個Python命令列工具
- 1.1.命令列的特點,以及Python的如何編寫命令列
- 1.2.如何組織程式碼結構.
- 2.釋出
- 2.1.註冊pypi賬戶
- 2.2.註冊在賬戶下面註冊Python包
- 2.3.上傳打包好的Python命令列工具.
- 3.完善程式碼
1.寫好一個Python命令列工具
寫好一個命令列工具首先要知道命令列工具是什麼?
在我看來,命令列工具就是一種完成某種型別的任務的終端程式.
也就是基本上沒有什麼使用者介面的程式.
由於基本上沒有什麼使用者介面,所以導致單個命令列的互動能力及其低下.但這種低下的互動性對於一些固定工作而言,簡直就是最靈活的工具.只需要輸入一些命令便可以完成某種型別的工作.實在是方便的很.
所以,某種程度上,終端程式低互動的缺點反而成了優點.
1.1.Python的如何編寫一個簡單的命令列
對於Python和命令列互動,我們很容易想出一個比較方便的方案.
sys.argv就是這樣的嘛!
我們很容易這樣寫程式碼.
1 |
python testargv.py thisisaargv1 |
甚至我們也可以這樣寫命令列,
1 |
python testargv.py thisisaargv1 -d -f 0 |
那麼,這樣寫的後果就是,不方便解析出(不是不能,是不方便) -d -f 0 以及 thisisaargv1.
不信的話,你解析一個下面場景的命令列試試,
1 2 3 4 |
# 使用者可能這樣輸入 danmu.fm http://www.douyutv.com/xiaocang -q 1 -v 2 danmu.fm -q 1 -v 2 http://www.douyutv.com/xiaocang # 當然,肯定還有漏寫啦,等等,你得需要轉型別,增加各種blablabla的描述吧,新增預設的引數值吧. |
於是Python就提供了一個非常好用的模組可以使用.叫做argparse.
上面的描述就變成了這個樣子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import argparse APP_DESC=""" 這就是描述 """ print(APP_DESC) if len(sys.argv) == 1: sys.argv.append('--help') parser = argparse.ArgumentParser() parser.add_argument('-q','--quality',type=int,default=0,help="download video quality : 1 for the standard-definition; 3 for the super-definition") parser.add_argument('-v','--verbose', default=0,help="print more debuging information") parser.add_argument('-s','--store',help="儲存流媒體檔案到指定位置") parser.add_argument('-c','--config',default=0,help="讀取~/.danmu.fm配置,請~/.danmu.fm指定資料庫") parser.add_argument('url',metavar='URL',nargs='+', help="zhubo page URL (http://www.douyutv.com/*/)") args = parser.parse_args() # 獲取對應引數只需要args.quality,args.url之類. url = (args.url)[0] print(url) #其他執行邏輯 |
儲存為danmu.py
這樣就可以執行命令
1 |
python danmu.py http://www.douyutv.com/xiaocang -q 1 -v 2 |
通過args就可以獲取引數,然後進行終端程式的引數初始化.
可是這和我們的要求還是不同嘛,我們不想多寫Python XXX,我們想直接XXX.就像這樣.
1 |
danmu.fm -q 1 -v 2 http://www.douyutv.com/xiaocang |
不急,下面就是了.
1.2.如何組織程式碼結構.
於是,現在就要開始組織程式碼結構了.
我們在最終的程式碼目錄大概是這樣的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
danmu.fm ├── README.md ├── danmufm │ ├── __init__.py │ ├── client │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── douyu_client.py │ │ └── douyu_danmu_client.py │ ├── danmu.py │ ├── misc │ │ ├── __init__.py │ │ ├── color_printer.py │ │ ├── downloaders.py │ │ └── player.py │ └── model │ ├── __init__.py │ └── douyu_msg.py ├── docs ├── setup.cfg ├── setup.py ├── sh.py └── tests |
這就是我上次寫的danmu.fm的程式碼目錄.
聰明的你這時候你注意到了:
- 主要的程式不是放在根目錄下面,而是放在第二目錄danmufm下面.
2.setup.cfg 是什麼鬼東西
3.setup.py 是什麼鬼東西
對於上面幾點,我們分別進行解釋
1.2.1 為什麼主要程式在第二目錄下
為了把主要的程式分離出來,放在第二目錄下面,這樣的待會打包以後多出很多資料夾就不會對原始碼造成干擾.
當然,由於把程式放在了第二目錄下面,所以,指令碼里面的from import語句應該使用相對路徑匯入.
相對路徑匯入的的時候需要注意執行的時候使用如下命令
1 |
python3 -m danmufm.danmu [xxxx] |
1.2.2 setup.cfg
填寫如下內容即可.
1 2 |
[metadata] description-file = README.md |
然後去寫Markdown的Readme就好了.
1.2.3 setup.py
這個是重頭戲了.
setup這個py檔案就是打包配置檔案.對這個程式是誰的,有什麼依賴,入口是什麼,等等等等的配置.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#-*- encoding: UTF-8 -*- from setuptools import setup, find_packages """ 打包的用的setup必須引入, """ VERSION = '0.1.1' setup(name='danmu.fm', version=VERSION, description="a tiny and smart cli player of douyutv,ximalayad,anmu based on Python", long_description='just enjoy', classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers keywords='python douyu danmu danmu.fm terminal', author='twocucao', author_email='twocucao@gmail.com', url='https://github.com/twocucao/doumu.fm', license='MIT', packages=find_packages(), include_package_data=True, zip_safe=True, install_requires=[ 'requests', ], entry_points={ 'console_scripts':[ 'danmu.fm = danmufm.danmu:main' ] }, ) |
官方有distutils這個包管理器工具,設定也非常的簡單,只是,它不支援entry_points屬性,由於無法使用entry_point,也就無法通過命令來跳轉到指定模組執行程式,這也就意味著,官方工具不方便寫成命令列.還是setuptools好.
上面需要注意的就是install_requires可以新增依賴.其他的你猜都可以猜出來是做什麼的.自己去看程式碼,我就不多說了.
2.釋出
所謂的釋出,就是將打包好的程式的某個版本釋出到某個倉庫中.
2.1.註冊pypi賬戶
到這個上面註冊賬號:
https://pypi.python.org/pypi
2.2.註冊在賬戶下面註冊Python包
進入對應專案根檔案,然後執行
1 |
python3 setup.py register |
這一步程式會讓你輸入剛剛註冊的賬號和密碼,然後註冊該包.註冊該包以後,你就有了一個小倉庫.可以存放不同版本的danmu.fm.
註冊的倉庫是可以在這個地址看到的,
https://pypi.python.org/pypi?%3Aaction=pkg_edit&name=danmu.fm
2.3.上傳打包好的Python命令列工具.
這裡需要藉助一個小工具,twine.twine是一個更加安全方便上傳打包好的程式碼的工具.
1 |
pip3 install twine |
接著開始打包,打包成兩個版本,一個是不需要build的版本,另一個是需要build的版本(順帶吐槽下,這兩個詭異的命名).
1 |
python setup.py sdist bdist_wheel |
於是剩下來的就顯而易見了,上傳build完畢的程式到倉庫中.
1 |
twine upload dist/danmu.fm-0.1.2* |
於是,安裝一下,測試是否成功
1 |
pip3 install danmu.fm --upgrade |
命令列的工具是這樣使用的.
1 |
danmu.fm -q 2 -v 1 http://www.douyutv.com/16789 |
3.完善
不斷的完善程式碼,然後打包終端程式釋出到倉庫給別人用,這就是整個的PIP打包釋出流程.
- 這個時候,你可能需要使用版本控制軟體.
- 你可能需要增多的程式碼的測試.