背景

我们在编写python程序时,程序中经常会提供多种功能或者模式,在实际使用时根据不同的参数使用不同的功能。那么如何获取命令行传入进来的参数呢?

一般方法

一般情况下,我们会使用 sys 模块,如

import sys

# 打印 sys 模块获取到的命令行参数
print(sys.argv)

或者,我们会使用 getopt 模块,如

import getopt

opts,args=getopt.getopt(sys.argv[1:],"i:ho:",["help","input=","output="])
# 打印选项列表
print(opts)
# 打印参数值列表
print(args) # 解析参数对应的值
for opts,arg in opts:
print(opts)
if opts=="optName":
print("optName is value is:", arg)

再或者,我们使用 argparse 模块,如

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-a', '--arg1', help='argument 1')
parser.add_argument('-b', '--arg2', help='argument 2')
parser.add_argument('-c', '--arg3', help='argument 3') args = parser.parse_args() print(args.arg1)
print(args.arg2)
print(args.arg3)

但,以这些,都不优雅,如果我们需要在不同的函数或者模块中传递使用命令行进来的参数,那这些零散的参数处理代码,将会带来不小的麻烦。我们需要通过一个专门的类来封装命令行的参数。

引入 DebugInfo 模块

pip install DebugInfo

定义一个命令行参数类,

定义一个入参类,继承自 入参基类,来专门负责解析和管理我们的传入参数,示例见:

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import * # endregion class 入参类(入参基类):
def __init__(self):
# 初始化基类
super().__init__(接口说明='这个脚本是用来演示如何使用【入参基类】来管理传入参数的') if __name__ == '__main__':
# 打印一下 入参基类 的说明文档
print(入参基类.__doc__)

上面的代码初步建立了入参类,继承自入参基类,我们通过打印入参基类doc 信息,可以查阅到相关的使用说明,如

如,我们通过 doc 的说明信息得知,这个入参基类其实是在 argparse 的基础上做了二次封装,然后提供了一些易用的接口。

下面的代码为入参类添加了我们需要接收的参数,并实例化了入参类,并解析了命令行参数:

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import * # endregion class 入参类(入参基类):
def __init__(self):
# 初始化基类
super().__init__(接口说明='这个脚本是用来演示如何使用【入参基类】来管理传入参数的') # 添加需要接收的参数
self._添加参数('a', int, '这是 a 参数, 请输入一个数字', 0)
self._添加参数('b', int, '这是 b 参数, 请输入一个数字', 0)
self._添加参数('运算', ['和', '差'], '请输入运算形式', '和') if __name__ == '__main__':
# 实例化入参类
入参 = 入参类() # 解析命令行参数
入参.解析入参() # 打印获取到的参数
print(入参.get('a'))
print(入参.get('b'))
print(入参.get('运算'))

上面的代码运行效果如:

当我们在命令行中使用 -h 参数时,还会有相应的参数帮助提示,如

当我们输入的参数不正确时,还有相应的错误提示,如

这么多功能,相对于我们输入的代码量来说,是不是物超所值?优雅至极?

百尺杆头,更进一步

上面的代码中,我们通过 入参.get('a') 这样的方式获取了参数 a 的值.这不够优雅.

如的代码中,我们通过在 入参类 中定义property的方法,将每一个参数成员定义对应的getter接口,这样就可以通过 入参.a 这种方式获取和使用参数值了.同时也获得了 IDE 的成员提示和代码补全支持.

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import * # endregion class 入参类(入参基类):
def __init__(self):
# 初始化基类
super().__init__(接口说明='这个脚本是用来演示如何使用【入参基类】来管理传入参数的') # 添加需要接收的参数
self._添加参数('a', int, '这是 a 参数, 请输入一个数字', 0)
self._添加参数('b', int, '这是 b 参数, 请输入一个数字', 0)
self._添加参数('运算', ['和', '差'], '请输入运算形式', '和') # region 访问器
@property
def a(self) -> int:
if 'a' in self._参数字典:
return self._参数字典['a'].值
else:
return 0 @a.setter
def a(self, 值: int):
if 'a' in self._参数字典:
if type(值) in [int, float]:
self._参数字典['a'].值 = int(值) @property
def b(self) -> int:
if 'b' in self._参数字典:
return self._参数字典['b'].值
else:
return 0 @b.setter
def b(self, 值: int):
if 'b' in self._参数字典:
if type(值) in [int, float]:
self._参数字典['b'].值 = int(值) @property
def 运算(self) -> str:
if '运算' in self._参数字典:
return self._参数字典['运算'].值
else:
return '' @运算.setter
def 运算(self, 值: str):
if '运算' in self._参数字典:
self._参数字典['运算'].值 = str(值)
# endregion if __name__ == '__main__':
# 实例化入参类
入参 = 入参类() # 解析命令行参数
入参.解析入参() # 打印获取到的参数
print(入参.a)
print(入参.b)
print(入参.运算)

如此优雅的命令行参数解析和管理方式,我相信你从来没有见过,独此一份了.

效率支持

上面的代码中,我们看到我们为每一个参数写一个 property 的接口,好麻烦啊.优雅个毛线.

no!no!no! 你能想到的需求,作者当然要支持上了.

下面的代码中, 我们通过 入参.转换为属性范式() 将每一个命令行参数自动生成其对应的访问器接口,并且自动送到您的粘贴板里,您唯一需要做的就是 ctrl-V, 惊不惊喜? 意不意外?

# -*- coding:UTF-8 -*-

# region 引入必要依赖
from DebugInfo.DebugInfo import * # endregion class 入参类(入参基类):
def __init__(self):
# 初始化基类
super().__init__(接口说明='这个脚本是用来演示如何使用【入参基类】来管理传入参数的') # 添加需要接收的参数
self._添加参数('a', int, '这是 a 参数, 请输入一个数字', 0)
self._添加参数('b', int, '这是 b 参数, 请输入一个数字', 0)
self._添加参数('运算', ['和', '差'], '请输入运算形式', '和') if __name__ == '__main__':
# 实例化入参类
入参 = 入参类() # 对每一个命令行参数,生成其对应的 访问器接口
入参.转换为属性范式()

上面的代码中, 入参.转换为属性范式() 的效果如:

共生成了32行代码,每个参数的setter, getter属性都给你准备好了, ctrl+V 是您唯一需要做的事情了.

不让告诉我你不知道在哪里 ctrl+V

如果你不希望命令行参数被setter, 你可以通过函数参数控制生成,如

if __name__ == '__main__':
# 实例化入参类
入参 = 入参类() # 对每一个命令行参数,生成其对应的 访问器接口
入参.转换为属性范式(setter=False)

小结

以上所分享的命令行参数解析+管理的方式,提供自 DebugInfo 模块内的 入参基类, 虽然是基于 argparse 的一个二次封装,但相对于直接使用 argparse, 确实方便和清晰不少.

python中,如何优雅的解析和管理命令行参数的更多相关文章

  1. python解析传入的命令行参数 argv

    python解析命令行参数主要有三种方法:sys.argv.argparse解析.getopt解析 方法一:sys.argv —— 命令行执行:python test_命令行传参.py 1,2,3 1 ...

  2. C语言笔记 12_可变参数&内存管理&命令行参数

    可变参数 有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数.C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数.下面的实例 ...

  3. getopts解析shell脚本命令行参数

    getopts命令格式 getopts optstring name [arg] optstring为所有可匹配选项组成的字符串,每个字母代表一个选项.如果字母后有冒号:,表明该选项需要选择参数.比如 ...

  4. 3.QT中QCommandLineParser和QCommandLineOption解析命令行参数

     1  新建项目 main.cpp #include <QCoreApplication> #include <QCommandLineParser> #include & ...

  5. python命令行参数处理模块 optparse 使用参考

    from optparse import OptionParser parser = OptionParser() parser.add_option( '-f', '--file', dest='f ...

  6. 7z命令行参数中的路径

    最近在自动化的过程中用到了7z命令行工具,发现其参数中的路径挺有意思的,在此总结一下.本文中所有demo使用的7z版本为:15.14 x64. 压缩某个文件夹 下面的命令会把g:\temp\目录和目录 ...

  7. Python中第三方的用于解析HTML的库:BeautifulSoup

    背景 在Python去写爬虫,网页解析等过程中,比如: 如何用Python,C#等语言去实现抓取静态网页+抓取动态网页+模拟登陆网站 常常需要涉及到HTML等网页的解析. 当然,对于简单的HTML中内 ...

  8. Python 中命令行参数解析工具 docopt 安装和应用

    什么是 docopt? 1.docopt 是一种 Python 编写的命令行执行脚本的交互语言. 它是一种语言! 它是一种语言! 它是一种语言! 2.使用这种语言可以在自己的脚本中,添加一些规则限制. ...

  9. 【Python】 配置解析ConfigParser & 命令行参数解析optparser

    ConfigParser ConfigParser包装了配置文件的读取和写入,使得python程序可以更加轻松操作配置文件了.这里的配置文件是指.ini的那种文件,基本格式如下 [section_a] ...

  10. python命令行参数解析模块argparse和docopt

    http://blog.csdn.net/pipisorry/article/details/53046471 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的o ...

随机推荐

  1. python第一章 学习笔记 计算机基础知识 Sublime Text 3

    ## 计算机是什么 在现实生活中,越来越无法离开计算机了 电脑.笔记本.手机.游戏机.汽车导航.智能电视 ... 计算机就是一个用来计算的机器! 目前来讲,计算机只能根据人类的指令来完成各种操作,人让 ...

  2. 【Unity3D】UI Toolkit样式选择器

    1 前言 ​ UI Toolkit简介 中介绍了样式属性,UI Toolkit容器 和 UI Toolkit元素 中介绍了容器和元素,本文将介绍样式选择器(Selector),主要包含样式类选择器(C ...

  3. 【不限框架】超好用的3d开源图片预览插件推荐

    今天给大家推荐一款超好用的图片预览插件-image-preview 简单说明 image-preview是一款主要面向移动端web应用,同时兼容pc,基于原生js,不限框架,react,vue,ang ...

  4. P1119 floyd

    最开始看错数据了没看到Q = 100 是50%的数据以为跑q遍floyd能过,结果只有30,其他全t 1.要注意题目中的条件,挖掘一些性质 2.本题的另一个关键的是要对floyd的过程原理比较熟悉,f ...

  5. k8s Redis安装部署

    一.文档简介 作者:lanjiaxuan 邮箱:lanheader@163.com 博客地址:https://www.cnblogs.com/lanheader/ 更新时间:2021-07-09 安装 ...

  6. LVS负载均衡群集——其二

    LVS-DR 通信四元素:源IP,源端口,目的IP,目的端口 主机A(客户端)-->VIP 主机B(调度器) 主机A(客户端)<--VIP 主机C(节点服务器) 通信五元素:源IP,源端口 ...

  7. 一起来探索CSS中margin属性的奥秘吧!!

    作者:WangMin 格言:努力做好自己喜欢的每一件事 众所周知 margin属性 是用来声明当前所设置或者指定元素所有外边距的宽度,或者设置各边上外边距的宽度.一直以来我认为它是一个很简单的属性,但 ...

  8. 谈谈SSO单点登录的设计实现

    谈谈SSO单点登录的设计实现 本篇将会讲讲单点登录的具体实现. 实现思路 其实单点登录在我们生活中很常见,比如学校的网站,有很多个系统,迎新系统,教务系统,网课系统.我们往往只需要登录一次就能在各个系 ...

  9. 线上SQL超时场景分析-MySQL超时之间隙锁

    前言 之前遇到过一个由MySQL间隙锁引发线上sql执行超时的场景,记录一下. 背景说明 分布式事务消息表:业务上使用消息表的方式,依赖本地事务,实现了一套分布式事务方案 消息表名:mq_messag ...

  10. Redis Functions 介绍之二

    首先,让我们先回顾一下上一篇讲的在Redis Functions中关于将key的名字作为参数和非key名字作为参数的区别,先看下面的例子.首先,我们先在一个Lua脚本文件mylib.lua中定义如下的 ...