问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何发布一个Python命令行工具

发布网友 发布时间:2022-04-21 23:06

我来回答

1个回答

热心网友 时间:2022-04-18 07:08

本文的目的也是非常简单:
写一个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 -q 1 -v 2
danmu.fm -q 1 -v 2
# 当然,肯定还有漏写啦,等等,你得需要转类型,增加各种blablabla的描述吧,添加默认的参数值吧.

于是Python就提供了一个非常好用的模块可以使用.叫做argparse.
上面的描述就变成了这个样子

Python

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 (*/)")
args = parser.parse_args()
# 获取对应参数只需要args.quality,args.url之类.
url = (args.url)[0]
print(url)
#其他执行逻辑

保存为danmu.py
这样就可以执行命令

1

python danmu.py -q 1 -v 2

通过args就可以获取参数,然后进行终端程序的参数初始化.
可是这和我们的要求还是不同嘛,我们不想多写Python XXX,我们想直接XXX.就像这样.

1

danmu.fm -q 1 -v 2

不急,下面就是了.
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 ?%3Aaction=list_classifiers
keywords='python douyu danmu danmu.fm terminal',
author='twocucao',
author_email='twocucao@gmail.com',
url='',
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账户
到这个上面注册账号:

2.2.注册在账户下面注册Python包
进入对应项目根文件,然后执行

1

python3 setup.py register

这一步程序会让你输入刚刚注册的账号和密码,然后注册该包.注册该包以后,你就有了一个小仓库.可以存放不同版本的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

3.完善
不断的完善代码,然后打包终端程序发布到仓库给别人用,这就是整个的PIP打包发布流程.
这个时候,你可能需要使用版本控制软件.
你可能需要增多的代码的测试.
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
鼠戴什么属相首饰最旺运 什么宝石最旺鼠 属鼠戴什么财运最旺 属鼠佩戴什么珠子最旺 这首钢琴曲叫什么名字?很多广播站结束的时候喜欢用的背景音乐. ...纯音乐,是钢琴曲,常用作感情倾诉类节目的背景音乐 ...背景音乐 有一首钢琴曲 同一节奏渐进重复,好多电视节目背景音乐... 脾虚的原因有哪些?脾虚是什么导致的? iGene 击音 听键DJ 蓝牙音频接收器 蓝色-购买最佳价格 1MORE 万魔 蓝牙音频接收器-高清无线认证,稳定连接,超长续航 python是不是基本是运行在 命令行 窗口下的 python编辑器方式和命令行方式的区别 Python的交互命令行在哪打开呢 怎么打开python 命令行模式 怎么在命令行窗口运行python -V? Python的命令行窗口是什么 电信版的iphone5合约机和裸机如何区分? 拜托求博雅小学堂Scratch入门编程课视频(20讲)的... 如何辨别中华香烟的真假 如何识别中华烟的真假? 如何辨别中华香烟的真假? 怎么区分硬中华香烟真假 怎样看中华烟的真假?扫条形码扫不出来是假的吗 怎么辨别硬盒中华烟的真假? 怎样识别中华烟的真假 如何区分中华香烟的真伪 如何识别硬中华烟真伪? 中华烟怎么鉴别是真是假? 整条中华烟真假如何辨别 中华香烟从外包装上怎么区别真假? python 的命令行参数究竟是什么 怎么用 有什么用?? python在命令行环境下运行时,显示拒绝访问,请大... python命令行怎么打开文件夹 Python如何开启命令行模式 入门Python的教程 python如何分别向两个cmd窗口输入指令 iphone5s合约机和裸机的区别. python 在命令窗口中输入没问题,在脚本中出错 老年人患有白血病的病因有哪些 老人为什么会得白血病 老年人为什么会的白血病 郑州72岁爷爷工地打工为救白血病孙女,白血病是哪... 哪位帮忙老年人白血病的原因? 引起老年人急性淋巴细胞白血病的原因有哪些? 老年人为什么会得白血病 白血病是怎么得上的? 老人头发变白和白血病的原因各是什么 白血病的病因会是什么? 老年人慢性淋巴细胞白血病是怎么引起的? 白血病是怎么引起的,又有那些症状,有那几种治疗...