argparse

Abstract

在命令窗口运行 Python 程序时,有时需要传入一些参数,就用到了 argparse 模块,它有非常强的解析命令行参数的能力。本文对该包进行简要介绍:

  • 原始的命令行参数获取方式 sys.argv
  • argparse 的基本用法;
  • 背后的运作机制;
  • shell 编程;
  • 更好的方式 configure.py

sys.argv

sys.argv 是一个列表,包含了在启动 Python 脚本时传递给解释器的命令行参数。第一个元素是脚本的名称(或路径),之后的元素是按顺序列出的命令行参数:

import sysprint(sys.argv)
print(f'Script name: {sys.argv[0]}')  # 脚本的名称
print(f'Argument 1: {sys.argv[1]}')  # 第一个命令行参数
print(f'Argument 2: {sys.argv[2]}')  # 第二个命令行参数

在命令行中输入:

python .\argparse_demo.py arg1 arg2

输出:

['.\\argparse_demo.py', 'arg1', 'arg2']
Script name: .\argparse_demo.py
Argument 1: arg1
Argument 2: arg2

其实就是 ‘python’ 命令后的内容。需要注意的是,sys.argv 中的命令行参数都是字符串类型

argparse

先从一个简单的例子开始:

import argparseparser = argparse.ArgumentParser(prog='ProgramName',description='What the program does',epilog='Text at the bottom of help'
)
parser.add_argument('filename')  # positional argument
parser.add_argument('-c', '--count')  # option that takes avalue
parser.add_argument('-v', '--verbose', action='store_true')  # on/off flagargs = parser.parse_args()
print(args)

命令行输入:python prog.py filename.txt -c 3 -v,得到:

Namespace(filename='filename.txt', count='3', verbose=True)

命令行输入:python prog.py -h,得到帮助信息:

usage: ProgramName [-h] [-c COUNT] [-v] filename  # prog='ProgramName'What the program does  # descriptionpositional arguments:  # 位置参数filenameoptional arguments:  # 可选参数-h, --help            show this help message and exit-c COUNT, --count COUNT-v, --verboseText at the bottom of help  # epilog

首先要说明的是两类参数,positional arguments 和 optional arguments,这类似于函数签名中的位置参数可选参数。此处:

  • 不以 '-' 开头的普通变量是位置参数,其顺序由其添加顺序决定;
  • '-''--' 开头的是可选参数,变量名由 --*** 决定,如此例中的 countverbose,若没有 --***,则由 -* 决定;

后面将进行更详细的说明。

这段例子干了三件事:

  • 创建参数解析器 parser = argparse.ArgumentParser(...)
  • 用函数 parser.add_argument(...) 添加了三个参数 filenamecountverbose
  • args = parser.parse_args() 解析参数。

现在要了解两个问题

  • argparse.ArgumentParser 是什么?
  • 如何添加和解析参数:parser.add_argumentargs = parser.parse_args()

argparse.ArgumentParser 是什么?

打印解析器对象print(parser) 输出的内容是:

ArgumentParser(prog='ProgramName',usage=None,description='What the program does',formatter_class=<class 'argparse.HelpFormatter'>,conflict_handler='error',add_help=True
)

可以看到这个对象现有六个参数,一眼就能看懂的有两个:

  • prog='ProgramName' 是程序脚本文件名,点到源码处,发现是这样的:
# default setting for prog
if prog is None:prog = _os.path.basename(_sys.argv[0])

程序名是可以设置的,不填的话,就默认为 _os.path.basename(_sys.argv[0])[上面有用]!但我们填了 prog='ProgramName'

  • description 字符串给出了程序的简要描述。

然后可以从 python prog.py -h 的输出中,得知:

  • usage:自定义用法说明。如果不指定,则会自动生成一个用法说明,如
usage: ProgramName [-h] [-c COUNT] [-v] filename

虽然实际上这么输入命令是不可行的。看看我们自己设置 usage 会发生什么:

parser = argparse.ArgumentParser(usage='hahaha!!!')

再输出 help 信息,得到的 usage 为:

usage: hahaha!!!
  • add_help:当 add_help=True 时,帮助选项会被添加到解析器中。可以通过在命令行中使用 -h--help 来触发该选项,并显示帮助文档。这就是为什么会多出一个可选参数 -h, --help 来!如果改为 False:
parser = argparse.ArgumentParser(add_help=False)

再命令行输入 python prog.py --help,则会报错,说明没有参数 --help

-h, --help 比较特别,给出了它,就会输出程序的帮助信息,包括:usage、description、positional arguments 和 optional arguments,而且不会执行脚本程序内容

剩下的两个要求助 GPT:

  • formatter_class:指定帮助文档输出的格式。常用的取值有 argparse.RawTextHelpFormatter(保留原始文本格式)和 argparse.ArgumentDefaultsHelpFormatter(包含参数的默认值)等。【主要是 description 和 epilog 换不换行吧!】
  • conflict_handler 用于指定在出现冲突的情况下如何处理。具体来说,它用于解决当多个参数具有相同的选项字符串时产生的冲突。接受以下值:
    ~~~~     ‘error’:默认值。当出现冲突时,抛出一个 ArgumentConflictError 异常。
    ~~~~     ‘resolve’:自动解决冲突,默认选择后面的参数。这意味着后面出现的参数将覆盖先前出现的参数。
    ~~~~     ‘ignore’:忽略冲突,保留先前出现的参数,忽略后面出现的参数。
    下面是使用 conflict_handler 参数的示例:
import argparseparser = argparse.ArgumentParser(conflict_handler='resolve')
parser.add_argument('-a', '--option', help='Option A')
parser.add_argument('-b', '--option', help='Option B')  # -a-b 具有相同的选项字符串args = parser.parse_args()

-a, --option 以及 -b, --option 都具有相同的选项字符串,即存在冲突。由于设置了 conflict_handler='resolve',后面出现的参数会覆盖先前出现的参数。因此,如果在命令行中提供了 -avalue1 -b value2,则 args.option 的值将是 'value2'

小结:以上就是对 argparse.ArgumentParser 对象参数的解释,没有特别有用的地方。

如何添加参数:parser.add_argument

def add_argument(self,*name_or_flags: str,action: str | Type[Action] = ...,nargs: int | str | _SUPPRESS_T | None = None,const: Any = ...,default: Any = ...,type: (str) -> _T | FileType = ...,choices: Iterable[_T] | None = ...,required: bool = ...,help: str | None = ...,metavar: str | tuple[str, ...] | None = ...,dest: str | None = ...,version: str = ...,**kwargs: Any
) -> Action
名称描述

action

指明应当如何处理一个参数

'store', 'store_const', 'store_true', 'append', 'append_const', 'count', 'help', 'version'

nargs

参数可被使用的次数

int, '?', '*''+'

const

存储一个常量值

default

当未提供某个参数时要使用的默认值

默认为 None

type

自动将参数转换为给定的类型

int, float, argparse.FileType('w') 或可调用函数

choices

将值限制为指定的可选项集合

['foo', 'bar'], range(1, 10)Container 实例

required

指明某个参数是必需的还是可选的

TrueFalse

help

某个参数的帮助消息

metavar

要在帮助中显示的参数替代显示名称

dest

指定要在结果命名空间中使用的属性名称

函数 parser.add_argument(...) 向解析器中添加命令行参数,并通过上表中的设置告诉解析器如何解析该参数,如 type=int 告诉解析器应当把该参数解析为 int 整数。下面逐一解释这些设置:

*name_or_flags

设置参数名。根据 Python 的语法,这个 *name_or_flags*,是可变位置参数,可接收多个实参,也意味着可以给添加的参数取多个名字?来试试:

parser.add_argument('filename', 'name')

命令行 python prog.py file.txt,报错:

ValueError: invalid option string 'filename': must start with a character '-'

无效的 option,即,多于一个的普通参数名,会被当作可选参数,且提示你应以 '-' 开头。

是的,上面的可选参数 '-c', '--count''-v', '--verbose',可以有多个名,可以有不止两个哦:

parser.add_argument('-c', '--count', '--cc', '---ddd')

可正常运行,且这四个名称都可用,不过最终的变量名由第一个横线数大于等于 2 的字符串决定,比如此处:args.count

action & const & default

指明应当如何处理一个可选参数,注意是可选参数,因为位置参数的灵活性很低,仅仅是简单地将出现在命令行中的非 - 字符串按顺序依次赋给位置参数,而可选参数要列出参数名,把要赋予的值跟在其后。

默认是 action='store',将跟在参数名后的字符串赋予该参数,如:

python prog.py filename.txt -c 3

将 3 赋给了 args.count。这是最常见的,实际上函数的这三个参数搭配使用相当灵活。下面以 -c, --count介绍常见的用法:

  • action='store' 时。将跟在 -c 后的 3 赋给 args.count;如果可选参数 -c, --count 未列出到命令行,则会将 default=***[默认default=None] 的值赋给 args.count
  • action='store_const' 时。-c 后不必跟随任何值,跟了也会被赋给位置参数args.count=const if 命令行中出现 -c else args.count=default;【const=***必须设置;此时不能再设置 type,因为 const 已经确定了】
  • action='store_true' 时。args.verbose=True if 命令行中出现 -v else args.verbose=False;【等价于上面的 const=True, default=False

简单来说,action='store_const' 时,const 和 default 二选一,action='store_true' 时,True 和 False 二选一。

  • append 系列很少用,区别在于 args.count 会被当作列表:
python prog.py filename.txt -c 3       # args.count=[3]
python prog.py filename.txt -c 3 -c 2  # args.count=[3, 2]
  • append_const 就类比吧;
  • count 就是计数:
parser.add_argument('-c', '--count', action='count', default=5)
python prog.py file.txt           # args.count=5
python prog.py file.txt -c -c -c  # args.count=3
nargs

控制 -c 接收几个参数:

  • nargs=int>0:接收 int 个参数
parser.add_argument('-c', '--count', nargs=1)
python prog.py file.txt -c 1  # args.count=['1']
# 结果是 list
parser.add_argument('-c', '--count', nargs=3)
python prog.py file.txt -c 1 2 3  # args.count=['1', '2', '3']
  • nargs='?':接收至多一个参数
parser.add_argument('-c', '--count', nargs='?', default=5)
python prog.py file.txt -c    # args.count=None, default=5 不起作用 
python prog.py file.txt -c 1  # args.count=['1']
  • nargs='+':至少一个;
  • nargs='*':任意个。
choices

固定参数可接受的值范围:

parser.add_argument('-c', '--count', type=int, choices=[1, 2, 3])  # 要和 type 一致
python prog.py file.txt -c 2  # args.count=2
python prog.py file.txt -c 4  # error
required

有点鸡肋,可选参数为什么还要搞出这么一个参数?大概是想实行 key=value 的参数供应形式,又不让 default 吧!

dest & metavar

前面说参数名是 args.count,那只是缺省这两个参数的情况。当:

parser.add_argument('-c', '--count', dest='true_name', metavar='help_name')

命令行输入 python prog.py file.txt --count 2,得到【注意 true_name】:

Namespace(filename='file.txt', true_name='2', verbose=False)

命令行输入 python prog.py -h,得到【注意 help_name】:

optional arguments:-h, --help            show this help message and exit-c help_name, --count help_name-v, --verbose

真正的参数名是由 dest=*** 决定的,而 metavar 则是显示在帮助信息中。

如何解析参数?

函数 parser.add_argument(...) 的源码内容相当复杂,但我们知道 parser.parse_args() 返回了一个 Namespace 对象:

args = parser.parse_args() = Namespace(filename='file.txt', true_name='2', verbose=False)

包含了所有参数。然后还可以看到很多:

setattr(self, name, kwargs[name])
setattr(namespace, self.dest, not option_string.startswith('--no-'))
setattr(namespace, self.dest, values)      # action='store'
setattr(namespace, self.dest, self.const)  # action='store_const'
setattr(namespace, self.dest, items)
setattr(namespace, self.dest, items)
...

清一色的为 namespace 对象设置属性 self.dest,就是刚才说的决定参数名的。上面各行应该就是对应不同的 action

其他

一个官方示例:可以给参数赋值任何对象

以下代码是一个 Python 程序,它获取一个整数列表并计算总和或者最大值:

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers',metavar='N',type=int,nargs='+',help='an integer for the accumulator'
)
parser.add_argument('--sum',dest='accumulate',action='store_const',const=sum,default=max,help='sum the integers (default: find the max)'
)
args = parser.parse_args()
print(args.accumulate(args.integers))

当使用适当的参数运行时,它会输出命令行传入整数的总和或者最大值:

python prog.py 1 2 3 4
4
python prog.py 1 2 3 4 --sum
10

函数 summax 也可作为参数的赋值。

ArgumentParser 中的参数 allow_abbrev

在不引起混淆的情况下,命令行参数允许缩写。

假如:

parser.add_argument('-opt')

那么命令行中写:

# 需要是 `opt` 的前缀
python prog.py -o 4
python prog.py -op 4
python prog.py -opt 4

都是一样的,得到变量名都是 args.opt

假如:

parser.add_argument('--option')

那么命令行中写:

python prog.py --o 4
python prog.py --op 4
python prog.py --opt 4
python prog.py --option 4

都是一样的,得到变量名都是 args.option

同时提供了 '-o', '--option' 的话,则最终的变量名为 'args.option',即双横杠的为变量名其他用法都一样。

parser.add_argument('-opt', '--option')

命令行中则只需写其前缀 -o, -op, -opt, ...,当然,-o 最简单。

【注】关于变量名,add_argument 中的参数 dest 才是最牛的,只要指定 dest='***',那最终的变量名就是 args.***,不论 '-o', '--option'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611189.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IPv6路由协议---IPv6动态路由(OSPFv3-4)

OSPFv3的链路状态通告LSA类型 链路状态通告是OSPFv3进行路由计算的关键依据,链路状态通告包含链路状态类型、链路状态ID、通告路由器三元组唯一地标识了一个LSA。 OSPFv3的LSA头仍然保持20字节,但是内容变化了。在LSA头中,OSPFv2的LS age、Advertising Router、LS Sequence…

Vue3技术解析(小册子)

随着 Vue 3 正式版本的发布&#xff0c;未来 Vue 3 将会成为前端的主流框架&#xff0c;这个毋庸置疑。Vue 3 在使用方面会兼容部分 Vue 2.x 的特性&#xff0c;比如 options API。 所以&#xff0c;究竟是要先学习 Vue 2 打好基础&#xff0c;还是直接学习 Vue 3 呢&#xff…

数据库系列MySQL:存储过程

# 创建一个名为ShowStu的存储过程&#xff0c;查询student表的内容 delimiter // create PROCEDURE ShowStu() begin select * from student; end// delimiter ;call ShowStu();# 存储过程的参数 1. IN输入参数 表示调用者向过程传入值&#xff08;传入值可以是字面量或变量&…

职场日常英语口语,成人英语培训学校,柯桥学英语推荐哪里

“玩手机”用英语怎么说&#xff1f;你的第一反应是不是&#xff1a;play the phone&#xff1f; 在英语中&#xff0c;play这个动词通常表示“玩耍、娱乐、操纵”等意思&#xff0c;而手机是一种工具&#xff0c;不是玩耍的对象。 换句话说&#xff0c;我们“玩手机”&#xf…

主食冻干哪款好?十大放心主食冻干名单推荐

作为养猫的人&#xff0c;我们都知道每天最担心的事情就是如何为心爱的猫咪选择一款高品质的猫粮。我们都希望为猫咪提供最好的营养&#xff0c;让它们健康快乐地成长。然而&#xff0c;近期的一些事件&#xff0c;如百利猫粮生虫和VE主食冻干掰开有虫&#xff0c;让我们不得不…

软件测试|Windows系统配置pytest+allure环境教程

前言 allure可以输出非常精美的测试报告&#xff0c;也可以和pytest进行完美结合&#xff0c;不仅可以渲染页面&#xff0c;还可以控制用例的执行。本文我们将介绍Windows系统中如何配置allure环境。 第一步&#xff1a;配置Java环境 因为allure的运行依赖于Java环境&#x…

Spring Security介绍

一、Spring Security&#xff1a; 1、简介&#xff1a;Spring Security 是一个非常流行和成功的 Java 应用开发框架。Spring Security 基于 Spring 框架&#xff0c;提供了一套 Web 应用安全性的完整解决方案。一般来说&#xff0c;Web 应用的安全性包括用户认证&#xff08;A…

vue3引用类型和基础类型深度克隆

深度克隆失效的一个例子 import { cloneDeep } from "lodash"; import { ref } from "vue";const navArr ref(["recommend","hot","new", ]) const list1: any ref([]) const list2: any ref([]) const list3: any ref(…

【Leetcode】15. 三数之和

【Leetcode】15. 三数之和 题目链接思路代码 题目链接 【Leetcode】15. 三数之和 思路 排序双指针去重 代码 func threeSum(nums []int) [][]int {// 切片升序排序sort.Slice(nums, func(i, j int) bool {return nums[i] < nums[j]})// 结果切片ans : [][]int{}n : len(n…

如何设置电脑桌面提醒,电脑笔记软件哪个好?

对于大多数上班族来说&#xff0c;每天要完成的待办事项实在太多了&#xff0c;如果不能及时去处理&#xff0c;很容易因为各种因素导致忘记&#xff0c;从而给自己带来不少麻烦。所以&#xff0c;我们往往会借助一些提醒类的软件将各项任务逐一记录下来&#xff0c;然后设置上…

微前端理论

学习微前端时&#xff0c;有几个核心概念和技术点是必须要理解和掌握的&#xff1a; 微前端架构&#xff1a; 微前端是一种将大型单体应用拆分为多个小型前端应用&#xff0c;每个应用可以独立开发、部署和升级&#xff0c;最后通过某种集成方式统一呈现给用户的前端架构模式。…

手持终端PDA定制厂家_5G安卓手持机设备/条形码扫描手持机PDA

手持终端PDA是一种功能强大的手持终端设备&#xff0c;具备一维码和二维码扫描功能&#xff0c;广泛应用于门票管理、零售、智能巡检、仓储物资管理、金融、快递等领域。 这款手持终端基于MT6877方案&#xff0c;搭载八核处理器(2xCortex-A78 2.4GHz 6xCortex-A55 2.0GHz)&…

高速PCB设计10大要点总结

学习高速PCB设计&#xff0c;掌握这10个知识点很重要&#xff01; 在高速PCB设计的学习中&#xff0c;有很多的知识点需要大家去了解和掌握&#xff0c;比如常见的信号完整性、反射、串扰、电源噪声、滤波等。本文和大家分享10个和高速PCB设计相关的重要知识&#xff0c;希望对…

ChatGPT4+Python近红外光谱数据分析及机器学习与深度学习建模进阶应用

2022年11月30日&#xff0c;可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT3.5&#xff0c;将人工智能的发展推向了一个新的高度。2023年4月&#xff0c;更强版本的ChatGPT4.0上线&#xff0c;文本、语音、图像等多模态交互方式使其在…

React16源码: React中的setState和forceUpdate源码实现

setState 和 forceUpdate 1 &#xff09; 概述 通过 class component 内部的 setState&#xff0c;以及 forceUpdate 去更新一个组件的过程在react的应用当中&#xff0c;我们只有 ReactDOM.render setState&#xff0c;以及 forceUpdate这几种种方式去更新react的应用是合理…

【Linux】修改Linux远程登录用户并授权,禁止root远程登录,修改Linux登录端口

一、修改Linux远程登录用户并授权 添加一个新的普通用户 用如下命令 adduser newuser 修改密码 passwd newuser 根据提示 输入密码 赋予newuser root 权限 修改 /etc/sudoers 文件 找到如下一行 &#xff0c;取消注释 ##Allows people in group wheel to run all commands %wh…

C# 学习笔记2-控制流与类型转换

控制流与类型转换 关于变量的简单操作判断循环类型转换异常处理检查数字类型的溢出 变量操作 一元运算符 Unary operators x&#xff0c;x&#xff0c;x--&#xff0c;--x。 这些运算符同 C。 postfix operator 后置运算符 还有 typeof(int)&#xff0c;sizeof(int)。 …

最新GPT4、AI绘画、DALL-E3文生图模型教程,GPT语音对话使用,ChatFile文档对话总结

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;文档对话总结DALL-E3文生图&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和…

【轮式移动机器人课程笔记 5】运动学仿真

L5 运动学仿真 本节重点&#xff1a; 如何理解推导出的运动学模型 回顾&#xff1a;机器人运动学模型 正向&#xff08;前向&#xff09;运动学模型反向运动学模型 基于MatLab运动学仿真 本节重点&#xff0c;如何利用matlab对运动学进行仿真 5.1 回顾运动学模型 [ x ˙ y …

离线AI聊天清华大模型(ChatGLM3)本地搭建

在特定的情况下&#xff0c;要保证信息安全的同时还能享受到AIGC大模型带来的乐趣和功能&#xff0c;那么&#xff0c;离线部署就能帮助到你&#xff0c;最起码&#xff0c;它是一个真正可用的方案。 大模型本身清华的 (ChatGLM3)&#xff0c;为的是对中文支持友好&#xff0c…