5

Python 中命令行解析模块 argparse 的使用

 1 year ago
source link: https://xujinzh.github.io/2022/11/22/python-argparse-useage/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Python 中命令行解析模块 argparse 的使用

2022-11-22technologypython

4 9.9k 9 分钟

熟悉 Linux 命令行的用户享受着对于不同命令指定不同参数的遍历,如 ls,表示打印当前目录下内容,而使用 ls /home 能够打印目录 /home 下的内容。这增加了 Linux 命令的使用范围,提高了用户体验。同样,在 Python 中也有类似的功能模块,那就是内置模块argparse, 其不仅能够自定义解析命令行参数(从 sys.argv 中解析这些参数),还能够解析 JSON 文件。本篇所有命令都是在 jupyter 中演示。

使用 argparse 常用步骤:

  1. import argparse # 导入模块;
  2. parser = argparse.ArgumentParser(prog="工程名", description="自定义描述信息") # 实例化一个解析器,在 jupyter 中使用 argparse.ArgumentParser? 可查看更详细的参数内容;
  3. parser.add_argument("-x", "--var_x", type=int, help="传入自变量") # 添加想要解析的命令行(可选)参数 var_x(例子)及配置,下面会对个配置进行详解。该步骤可重复添加多个不同的参数;
  4. args = parser.parse_args() # 解析参数;
  5. args.__dict__.update(d) # 使用字典 d 更新参数;
  6. args.var_x # 打印或使用某个参数;

命令行调用例子:

# 用户自定义参数 var_x 的值,运行 main.py,得到结果
python main.py --var_x 3

上面的步骤中,用户可灵活使用步骤 3 自定义解析参数,下面进行详细解释。

add_argument 配置

在上面步骤 3 中,用户可自定义添加待解析的参数以及该参数的配置,如取值类型、取值范围、默认值、参数帮助信息等。常用的配置如下:

配置项名 描述 取值
name or flags 一个命令或者一个选项字符串的列表,例如位置参数 var_x 或者可选参数 -f, --foo 字符串
action 指定如何处理该参数 'store', 'store_const', 'store_true', 'append', 'append_const', 'count', 'help', 'version'
choices 将参数取值限制在特定范围内 [1, 2]range(10) 或其他容器对象
const 存储一个常量值
default 当参数在命令行为指定值时使用的默认值 默认为 None
dest 指定结果命名空间(namespace)中使用的属性名称
help 参数的帮助信息
metavar 参数的备用显示名称,如帮助中所示
nargs 参数可以使用的次数 int'?''*''+'argparse.REMAINDER
required 指示参数是必需的还是可选的 TrueFalse
type 自动将参数转换为给定类型 intfloatargparse.FileType('w') 或 可调用函数

name or flags

add_argument() 方法必须知道是否需要可选参数(如 -x--var_x)或位置参数(如 var_x)。因此,传递给 add_argument() 的第一个参数必须是一系列标志或一个简单的参数名称。

可选参数创建方法:

parser.add_argument('-x', '--var_x')

位置参数创建方法:

parser.add_argument('var_x')

可选参数在命令行解析时,必须指定可选参数的名字,位置参数则是按照添加 add_argument 的位置依次赋值,当遇到可选参数时自动跳过。如:

%%writefile /workspace/hello/t.py

import argparse

def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("x")
parser.add_argument("-z", "--var_z")
parser.add_argument("y")
return parser

if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print("x: ", args.x)
print("z: ", args.var_z)
print("y: ", args.y)
%%bash
cd /workspace/hello/
python t.py 1 -z 2 3
# python t.py 1 --var_z 2 3
x:  1
z: 2
y: 3

action

ArgumentParser 对象将命令行参数与动作相关联。这些动作可以做与它们相关联的命令行参数的任何事,尽管大多数动作只是简单的向 parse_args() 返回的对象上添加属性。action 命名参数指定了这个命令行参数应当如何处理。常用的动作有: 'store', 'store_const', 'store_true', 'append', 'append_const', 'count', 'help', 'version', 'extend'

这里只针对 store_true 进行演示,其他参见:argparse

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-v", "--verbose", action="store_true")
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
if args.verbose:
print("long logs")
else:
print("short logs")
%%bash
cd /workspace/hello/
python t.py --verbose
long logs

如果不指定,则赋值 false

%%bash
cd /workspace/hello/
python t.py
short logs

choices

命令行赋值时,只有取值在 choices 中的才通过。例子:

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-x", "--var_x", choices=["0a", "0b", "0c"])
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print(args.var_x)
%%bash
cd /workspace/hello/
python t.py -x 0a
0a

如果取值不在 choices 中则报错。

const

default

有时候,一些参数在命令行赋值时常被忽略,如果这些参数有 default 默认值,则不会导致程序运行中出错。

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument('-x', "--var_x", default=42)
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print(args.var_x)
%%bash
cd /workspace/hello/
python t.py
42

定义参数在代码中的新名称。

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-x", "--var_x", dest="varX")
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print(args.varX) # 调用时使用区别于命令行显示的变量名
%%bash
cd /workspace/hello/
python t.py -x 3
3

显示参数的帮助信息。当用户请求帮助时(在命令行使用 -h--help 的方式)。

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-x", "--var_x", help="自变量 x 的值")
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print(args.var_x)
%%bash
cd /workspace/hello/
python t.py -h
usage: t.py [-h] [-x VAR_X]

python argparser

options:
-h, --help show this help message and exit
-x VAR_X, --var_x VAR_X 自变量 x 的值

metavar

help 一节中可以发现打印的帮助信息,变量名都是大写,使用参数 metavar 可以指定打印时变量名。

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-x", "--var_x", metavar='var-x')
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print(args.var_x)
%%bash
cd /workspace/hello/
python t.py -h
usage: t.py [-h] [-x var-x]

python argparser

options:
-h, --help show this help message and exit
-x var-x, --var_x var-x

nargs

add_argument() 方法中如果不添加 nargs 参数,则默认在命令行中可选或位置参数的后面值作为参数的取值,如果增加 nargs,则命令可选或位置参数后的 nargs 个值作为一个列表元素赋值给参数。nargs 支持的值有:

  1. N # 一个整数
  2. ‘+’ # 匹配参数后面至少一个值,可匹配多个值
  3. ‘*’ # 匹配参数后面至少0个值,可匹配多个值

更多请参考:argparse

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-x", "--var_x")
parser.add_argument("-t", "--theta", nargs=2)
parser.add_argument("-g", "--gamma", nargs=1)
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print("var_x: ", args.var_x)
print("theta: ", args.theta)
print("gamma: ", args.gamma)
%%bash
cd /workspace/hello/
python t.py -x 1 -t 30 60 -g 0.5
var_x:  1
theta: ['30', '60']
gamma: ['0.5']

required

通常,argparse 模块会认为 -f--bar 等旗标是指明 可选的 参数,它们总是可以在命令行中被忽略。 要让一个选项成为 必需的,则可以将 True 作为 required= 关键字参数传给 add_argument():

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("-x", "--var_x", required=True)
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print("var_x: ", args.var_x)
%%bash
cd /workspace/hello/
python t.py -x 1
var_x:  1

如果在命令行不指定参数则会报错,即使增加了 default 参数也会报错。

默认情况下,解析器会将命令行解析的值作为字符串赋值给参数,通过指定 type 可以将解析为指定类型的值。

%%writefile /workspace/hello/t.py

import argparse


def t():
parser = argparse.ArgumentParser(description="python argparser")
parser.add_argument("count", type=int)
parser.add_argument("distance", type=float)
parser.add_argument("street", type=ascii, help="ascii 码字符")
parser.add_argument("code_point", type=ord, help="单个字符")
return parser


if __name__ == "__main__":
parser = t()
args = parser.parse_args()
print("count: ", args.count)
print("distance: ", args.distance)
print("street: ", args.street)
print("code_point: ", args.code_point)
%%bash
cd /workspace/hello/
python t.py 1 2.0 'a' '天'
count:  1
distance: 2.0
street: 'a'
code_point: 22825

解析 JSON

有时候,一个工程有多个开发人员开发,每个子模块都有自定义的参数,常常将参数记录在 JSON 中,使用时直接从 JSON 中读取参数的取值即可。

读取 JSON

%%writefile /workspace/hello/t.py

import argparse
import os, json

def parse_json(json_file):

parser = argparse.ArgumentParser(description="python argparser")
if json_file is not None and os.path.exists(json_file):
with open(json_file, 'r') as jf:
parser.__dict__.update(json.load(jf))
return parser


if __name__ == "__main__":
# 把参数写入JSON
d = {'a': 1, 'b': 2}
json_file = 't.json'
with open(json_file, 'w') as jf:
json.dump(d, jf)
# 从JSON中读取参数
args = parse_json(json_file)
print(args)
print(args.a)
print(args.b)
%%bash
cd /workspace/hello/
python t.py
ArgumentParser(prog='t.py', usage=None, description='python argparser', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
1
2

JSON 更新参数

%%writefile /workspace/hello/t.py

import argparse
import json
import os


def parse_json(json_file):
parser = argparse.ArgumentParser(description="python argparser")
if json_file is not None and os.path.exists(json_file):
with open(json_file, "r") as jf:
parser.__dict__.update(json.load(jf))
return parser


def update_parse(args, json_file):
if json_file is not None and os.path.exists(json_file):
with open(json_file, "r") as jf:
args.__dict__.update(json.load(jf))
return args


if __name__ == "__main__":
# 把参数1写入JSON
d1 = {"a": 1, "b": 2}
json_file = "t.json"
with open(json_file, "w") as jf:
json.dump(d1, jf)
# 把参数2写入JSON
d2 = {"a": 10, "b": 20}
json_file_new = "t-new.json"
with open(json_file_new, "w") as jf:
json.dump(d2, jf)
# 从JSON中读取参数
args = parse_json(json_file)
print(args)
print(args.a)
print(args.b)
args = update_parse(args, json_file_new)
print(args)
print(args.a)
print(args.b)
%%bash
cd /workspace/hello/
python t.py
ArgumentParser(prog='t.py', usage=None, description='python argparser', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
1
2
ArgumentParser(prog='t.py', usage=None, description='python argparser', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
10
20

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK