argparse python 模块的文档虽然我敢肯定,但对于我小小的初学者大脑来说,现在掌握的内容太多了。我不需要在命令行上进行数学运算,也不需要干预屏幕上的格式行或更改选项字符。我想要做的就是“如果 arg 是 A,则执行此操作,如果 B 执行此操作,如果以上都没有显示帮助并退出”。
16 回答
这是我使用的方式argparse
(使用多个参数):
parser = argparse.ArgumentParser(description='Description of your program')
parser.add_argument('-f','--foo', help='Description for foo argument', required=True)
parser.add_argument('-b','--bar', help='Description for bar argument', required=True)
args = vars(parser.parse_args())
args
将是一个包含参数的字典:
if args['foo'] == 'Hello':
# code here
if args['bar'] == 'World':
# code here
在您的情况下,只需添加一个参数。
我对原始问题的理解是双重的。首先,就最简单的 argparse 示例而言,我很惊讶我在这里没有看到它。当然,为了简单起见,这也是开销很小的开销,但它可能会让你开始。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()
if args.a == 'magic.name':
print 'You nailed it!'
但是现在需要这个位置参数。如果你在调用这个程序时忽略它,你会得到一个关于缺少参数的错误。这使我进入原始问题的第二部分。Matt Wilkie 似乎想要一个没有命名标签的可选参数( --option 标签)。我的建议是修改上面的代码如下:
...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
print 'I can tell that no argument was given and I can deal with that here.'
elif args.a == 'magic.name':
print 'You nailed it!'
else:
print args.a
很可能有一个更优雅的解决方案,但这很有效并且是极简主义的。
该argparse
文档相当不错,但遗漏了一些可能不明显的有用细节。(@Diego Navarro 已经提到了其中的一些,但我会尝试稍微扩展他的答案。)基本用法如下:
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()
您返回的对象parse_args()
是“命名空间”对象:其成员变量以您的命令行参数命名的对象。Namespace
对象是您如何访问参数以及与它们关联的值:
args = parser.parse_args()
print (args.my_foo)
print (args.bar_value)
(请注意,argparse
在命名变量时将参数名称中的“-”替换为下划线。)
在许多情况下,您可能希望将参数简单地用作没有值的标志。您可以像这样在 argparse 中添加它们:
parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')
上面将分别创建名为 'foo' 且值为 True 的变量和名为 'no_foo' 的值为 False 的变量:
if (args.foo):
print ("foo is true")
if (args.no_foo is False):
print ("nofoo is false")
另请注意,您可以在添加参数时使用“必需”选项:
parser.add_argument('-o', '--output', required=True)
这样,如果您在命令行中省略此参数,argparse
将告诉您它丢失并停止执行您的脚本。
最后,请注意,可以使用该vars
函数创建参数的 dict 结构,如果这让您的生活更轻松。
args = parser.parse_args()
argsdict = vars(args)
print (argsdict['my_foo'])
print (argsdict['bar_value'])
如您所见,vars
返回一个 dict,其中您的参数名称作为键,它们的值作为,呃,值。
您可以执行许多其他选项和操作,但这应该涵盖最重要、最常见的使用场景。
Matt 询问 argparse 中的位置参数,我同意 Python 文档在这方面缺乏。在大约 20 页显示解析和使用位置参数的页面中,没有一个完整的示例。
这里的其他答案都没有显示位置参数的完整示例,所以这是一个完整的示例:
# tested with python 2.7.1
import argparse
parser = argparse.ArgumentParser(description="An argparse example")
parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')
args = parser.parse_args()
if args.action == "install":
print("You asked for installation")
else:
print("You asked for something other than installation")
# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)
# But this works:
print(getattr(args, 'foo-bar'))
让我失望的是 argparse 会将命名参数“--foo-bar”转换为“foo_bar”,但是名为“foo-bar”的位置参数保持为“foo-bar”,这使得如何不那么明显在你的程序中使用它。
请注意我的示例末尾附近的两行 - 这两行都无法获取 foo-bar 位置参数的值。第一个显然是错误的(它是一个算术表达式 args.foo 减去 bar),但第二个也不起作用:
AttributeError: 'Namespace' object has no attribute 'foo_bar'
如果要使用该foo-bar
属性,则必须使用getattr
,如我示例的最后一行所示。疯狂的是,如果您尝试dest=foo_bar
将属性名称更改为更易于访问的名称,您会收到一条非常奇怪的错误消息:
ValueError: dest supplied twice for positional argument
以下是上述示例的运行方式:
$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments
$ python test.py -h
usage: test.py [-h] action foo-bar
An argparse example
positional arguments:
action The action to take (e.g. install, remove, etc.)
foo-bar Hyphens are cumbersome in positional arguments
optional arguments:
-h, --help show this help message and exit
$ python test.py install foo
You asked for installation
foo
另一个摘要介绍,受这篇文章的启发。
import argparse
# define functions, classes, etc.
# executes when your script is called from the command-line
if __name__ == "__main__":
parser = argparse.ArgumentParser()
#
# define each option with: parser.add_argument
#
args = parser.parse_args() # automatically looks at sys.argv
#
# access results with: args.argumentName
#
参数由以下组合定义:
parser.add_argument( 'name', options... ) # positional argument
parser.add_argument( '-x', options... ) # single-char flag
parser.add_argument( '-x', '--long-name', options... ) # flag with long name
常见的选项有:
- help : 使用此参数时
--help
的描述。 - default:如果省略 arg,则为默认值。
- 类型:如果你期望一个
float
或int
(否则是str
)。 - dest : 为标志指定不同的名称(例如
'-x', '--long-name', dest='longName'
)。
注意:默认情况下--long-name
使用args.long_name
- action : 用于特殊处理某些参数
store_true, store_false
:对于布尔参数
'--foo', action='store_true' => args.foo == True
store_const
:与选项一起使用const
'--foo', action='store_const', const=42 => args.foo == 42
count
:对于重复的选项,如./myscript.py -vv
'-v', action='count' => args.v == 2
append
:对于重复的选项,如./myscript.py --foo 1 --foo 2
'--foo', action='append' => args.foo == ['1', '2']
- required:如果需要标志,或者不需要位置参数。
- nargs:用于捕获 N args 的标志
./myscript.py --foo a b => args.foo = ['a', 'b']
- 选择:限制可能的输入(指定为字符串列表,或 ints if
type=int
)。
这主要归功于@DMH,这是我在学习项目中提出的...
演示代码:
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--flag', action='store_true', default=False) # can 'store_false' for no-xxx flags
parser.add_argument('-r', '--reqd', required=True)
parser.add_argument('-o', '--opt', default='fallback')
parser.add_argument('arg', nargs='*') # use '+' for 1 or more args (instead of 0 or more)
parsed = parser.parse_args()
# NOTE: args with '-' have it replaced with '_'
print('Result:', vars(parsed))
print('parsed.reqd:', parsed.reqd)
if __name__ == "__main__":
main()
这可能已经发展并且可以在线获得:command-line.py
给这个代码一个锻炼的脚本:command-line-demo.sh
请注意Python HOWTOs中的Argparse 教程。它从最基本的示例开始,例如:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)
并进展到不太基本的那些。
有一个带有预定义选项的示例,例如询问的内容:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
print("{}^2 == {}".format(args.square, answer))
else:
print(answer)
代码文件:argparseDemo.py
简单:普通情况
- 名称(缩写,完整),在帮助下
import argparse argParser = argparse.ArgumentParser() argParser.add_argument("-n", "--name", help="your name") args = argParser.parse_args() print("args=%s" % args) print("args.name=%s" % args.name)
- 称呼
python argparseDemo.py -n Crifan
python argparseDemo.py --name Crifan
- 输出:
args=Namespace(name='Crifan')
和args.name=Crifan
- 称呼
- 类型
argParser.add_argument("-a", "--age", type=int, help="your current age") print("type(args.age)=%s" % type(args.age))
- 称呼:
python argparseDemo.py --age 30
- 输出:
type(args.age)=<class 'int'>
和args.age=30
- 称呼:
- 必需的
argParser.add_argument("-a", "--age", required=True, type=int, help="your current age")
- 称呼:
python argparseDemo.py
- 输出:错误
argparseDemo.py: error: the following arguments are required: -a/--age
- 称呼:
- 默认
argParser.add_argument("-a", "--age", type=int, default=20, help="your current age. Default is 20")
- 称呼:
python argparseDemo.py
- 输出:
args.age=20
- 称呼:
- 选择
argParser.add_argument("-f", "--love-fruit", choices=['apple', 'orange', 'banana'], help="your love fruits")
- 称呼:
python argparseDemo.py -f apple
- 输出:
args=Namespace(love_fruit='apple')
和args.love_fruit=apple
- 称呼:
- 多参数
argParser.add_argument("-f", "--love-fruit", nargs=2, help="your love fruits")
- 称呼:
python argparseDemo.py -f apple orange
- 输出:
args.love_fruit=['apple', 'orange']
- 称呼:
细节
最简单的:-x
代码:
import argparse argParser = argparse.ArgumentParser() argParser.add_argument("-a") # most simple -> got args.a, type is `str` args = argParser.parse_args() print("args.a=%s" % args.a)
用法 = 在命令行中运行
python argparseDemo.py -a 30
- 或者:
./argparseDemo.py -a 30
- make
argparseDemo.py
是可执行的- 如果没有,请添加:
chmod +x argparseDemo.py
- 如果没有,请添加:
- make
- 或者:
输出
args.a=30
笔记
- 默认类型是
str
argParser.add_argument("-a")
==argParser.add_argument("-a", type=str)
print("type(args.a)=%s" % type(args.a))
->type(args.a)=<class 'str'>
args
类型是Namespace
print("type(args)=%s" % type(args))
->type(args)=<class 'argparse.Namespace'>
args
值为Namespace(a='30')
print("args=%s" % args)
->args=Namespace(a='30')
- 所以我们可以调用/使用
args.a
- 默认类型是
参数名称
完整的参数名称:--xxx
- 代码
argParser.add_argument("-a", "--age")
- 用法
python argparseDemo.py -a 30
- 或者:
python argparseDemo.py --age 30
- 或者:
- 获取解析值:
args.age
- 注意:NOT
args.a
和NOT 存在args.a
- 注意:NOT
包含多个单词的完整参数名称:--xxx-yyy
- 代码
argParser.add_argument("-a", "--current-age")
- 获取解析值:args。目前年龄
添加帮助说明:help
- 代码
argParser.add_argument("-a", help="your age") # with help
- 输出
- 使用
--help
可以看说明 python argparseDemo.py --help usage: argparseDemo.py [-h] [-a A] optional arguments: -h, --help show this help message and exit -a A your age
- 使用
指定参数类型:type
- 代码
argParser.add_argument("-a", type=int) # parsed arg is `int`, not default `str`
- 输出
print("type(args.a)=%s" % type(args.a))
->type(args.a)=<class 'int'>
print("args=%s" % args)
->args=Namespace(a=30)
添加默认值:default
- 代码
argParser.add_argument("-a", type=int, default=20) # if not pass a, a use default value: 20
- 影响
- 用法:
python argparseDemo.py
- 输出:
print("args.age=%s" % args.age)
->args=Namespace(a=20)
- 用法:
你也可以使用plac(一个 wrapper around argparse
)。
作为奖励,它会生成简洁的帮助说明 - 见下文。
示例脚本:
#!/usr/bin/env python3
def main(
arg: ('Argument with two possible values', 'positional', None, None, ['A', 'B'])
):
"""General help for application"""
if arg == 'A':
print("Argument has value A")
elif arg == 'B':
print("Argument has value B")
if __name__ == '__main__':
import plac
plac.call(main)
示例输出:
没有提供参数 - example.py
:
usage: example.py [-h] {A,B}
example.py: error: the following arguments are required: arg
提供了意外的参数 - example.py C
:
usage: example.py [-h] {A,B}
example.py: error: argument arg: invalid choice: 'C' (choose from 'A', 'B')
提供了正确的参数 - example.py A
:
Argument has value A
完整的帮助菜单(自动生成) - example.py -h
:
usage: example.py [-h] {A,B}
General help for application
positional arguments:
{A,B} Argument with two possible values
optional arguments:
-h, --help show this help message and exit
简短说明:
参数的名称通常等于参数名称 ( arg
)。
参数后面的元组注解arg
含义如下:
- 说明 (
Argument with two possible values
) - 参数类型 - 'flag'、'option' 或 'positional' 之一(
positional
) - 缩写 (
None
) - 参数值的类型 - 例如。浮点数,字符串 (
None
) - 受限选择集 (
['A', 'B']
)
文档:
要了解有关使用plac的更多信息,请查看其出色的文档:
补充其他人所说的:
我通常喜欢使用 'dest' 参数来指定变量名,然后使用 'globals().update()' 将这些变量放在全局命名空间中。
用法:
$ python script.py -i "Hello, World!"
代码:
...
parser.add_argument('-i', '--input', ..., dest='inputted_variable',...)
globals().update(vars(parser.parse_args()))
...
print(inputted_variable) # Prints "Hello, World!"
我浏览了所有示例和答案,但在某种程度上,它们并没有满足我的需求。所以我会给她列出一个我需要更多帮助的场景,我希望这可以更多地解释这个想法。
最初的问题
我需要开发一个工具来获取文件来处理它,它需要一些可选的配置文件来配置工具。
所以我需要的是如下
mytool.py file.text -config config-file.json
解决方案
这是解决方案代码
import argparse
def main():
parser = argparse.ArgumentParser(description='This example for a tool to process a file and configure the tool using a config file.')
parser.add_argument('filename', help="Input file either text, image or video")
# parser.add_argument('config_file', help="a JSON file to load the initial configuration ")
# parser.add_argument('-c', '--config_file', help="a JSON file to load the initial configuration ", default='configFile.json', required=False)
parser.add_argument('-c', '--config', default='configFile.json', dest='config_file', help="a JSON file to load the initial configuration " )
parser.add_argument('-d', '--debug', action="store_true", help="Enable the debug mode for logging debug statements." )
args = parser.parse_args()
filename = args.filename
configfile = args.config_file
print("The file to be processed is", filename)
print("The config file is", configfile)
if args.debug:
print("Debug mode enabled")
else:
print("Debug mode disabled")
print("and all arguments are: ", args)
if __name__ == '__main__':
main()
我将在多个增强中展示解决方案以展示这个想法
第一轮:列出论点
将所有输入列为强制输入,因此第二个参数将是
parser.add_argument('config_file', help="a JSON file to load the initial configuration ")
当我们获得此工具的帮助命令时,我们会发现以下结果
(base) > python .\argparser_example.py -h
usage: argparser_example.py [-h] filename config_file
This example for a tool to process a file and configure the tool using a config file.
positional arguments:
filename Input file either text, image or video
config_file a JSON file to load the initial configuration
optional arguments:
-h, --help show this help message and exit
当我执行如下
(base) > python .\argparser_example.py filename.txt configfile.json
结果将是
The file to be processed is filename.txt
The config file is configfile.json
and all arguments are: Namespace(config_file='configfile.json', filename='filename.txt')
但是配置文件应该是可选的,我从参数中删除了它
(base) > python .\argparser_example.py filename.txt
结果将是:
usage: argparser_example.py [-h] filename config_file
argparser_example.py: error: the following arguments are required: c
这意味着我们的工具有问题
第二轮:优化
因此,为了使其成为可选,我将程序修改如下
parser.add_argument('-c', '--config', help="a JSON file to load the initial configuration ", default='configFile.json', required=False)
帮助结果应该是
usage: argparser_example.py [-h] [-c CONFIG] filename
This example for a tool to process a file and configure the tool using a config file.
positional arguments:
filename Input file either text, image or video
optional arguments:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
a JSON file to load the initial configuration
所以当我执行程序时
(base) > python .\argparser_example.py filename.txt
结果将是
The file to be processed is filename.txt
The config file is configFile.json
and all arguments are: Namespace(config_file='configFile.json', filename='filename.txt')
有像这样的论点
(base) > python .\argparser_example.py filename.txt --config_file anotherConfig.json
结果将是
The file to be processed is filename.txt
The config file is anotherConfig.json
and all arguments are: Namespace(config_file='anotherConfig.json', filename='filename.txt')
第 3 轮:增强功能
将标志名称从 更改为--config_file
, --config
同时保持变量名称不变,我们修改代码以包含dest='config_file'
以下内容:
parser.add_argument('-c', '--config', help="a JSON file to load the initial configuration ", default='configFile.json', dest='config_file')
命令将是
(base) > python .\argparser_example.py filename.txt --config anotherConfig.json
要添加对具有调试模式标志的支持,我们需要在参数中添加一个标志以支持布尔调试标志。为了实现它,我添加了以下内容:
parser.add_argument('-d', '--debug', action="store_true", help="Enable the debug mode for logging debug statements." )
工具命令将是:
(carnd-term1-38) > python .\argparser_example.py image.jpg -c imageConfig,json --debug
结果将是
The file to be processed is image.jpg
The config file is imageConfig,json
Debug mode enabled
and all arguments are: Namespace(config_file='imageConfig,json', debug=True, filename='image.jpg')
对此的新手,但将 Python 与 Powershell 相结合并使用此模板,其灵感来自于一个深入而出色的Python 命令行参数 – 真正的 Python
您可以在其中做很多事情init_argparse()
,我在这里只介绍最简单的场景。
import argparse
- 使用
if __name__ == "__main__": main()
模式从终端执行 - 解析
main()
函数中没有参数的参数 - 定义一个
init_argparse()
函数- 通过调用创建解析器对象
argparse.ArgumentParser()
- 声明一个或多个参数
parser.add_argument("--<long_param_name>")
- 返回解析器
- 通过调用创建解析器对象
args
通过调用创建对象来解析 argsparser.parse_args()
param1
用,param2
, ...定义一个函数- 将
function_proper
参数分配为args
对象 的属性的调用- 例如`function_proper(param1=args.param1, param2=args.param2)
- 在 shell 中使用命名参数调用模块:
- 例如
python foobar.py --param1="foo" --param2=="bar"
- 例如
#file: foobar.py
import argparse
def function_proper(param1, param2):
#CODE...
def init_argparse() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser()
parser.add_argument("--param1")
parser.add_argument("--param2")
return parser
def main() -> None:
parser = init_argparse()
args = parser.parse_args()
function_proper(param1=args.param1, param2=args.param2)
if __name__ == "__main__":
main()
>>> python .\foobar.py --param1="foo" --param2=="bar"
使用 argparse 并修改“-h”/“--help”开关以显示您自己的个人代码帮助说明的一个非常简单的方法是将默认帮助设置为 False,您还可以添加任意数量的附加 .add_arguments :
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help',
help='To run this script please provide two arguments')
parser.parse_args()
运行:python test.py -h
输出:
usage: test.py [-h]
optional arguments:
-h, --help To run this script please provide two arguments
由于您尚未澄清参数“A”和“B”是位置的还是可选的,所以我将两者混合。
默认情况下需要位置参数。如果不给出,则会抛出“给出的参数很少”,而以它们的名字命名的可选参数则不是这种情况。默认情况下,该程序将接受一个数字并返回其平方,如果使用立方体选项,它将返回其立方体。
import argparse
parser = argparse.ArgumentParser('number-game')
parser.add_argument(
"number",
type=int,
help="enter a number"
)
parser.add_argument(
"-c", "--choice",
choices=['square','cube'],
help="choose what you need to do with the number"
)
# all the results will be parsed by the parser and stored in args
args = parser.parse_args()
# if square is selected return the square, same for cube
if args.c == 'square':
print("{} is the result".format(args.number**2))
elif args.c == 'cube':
print("{} is the result".format(args.number**3))
else:
print("{} is not changed".format(args.number))
用法
$python3 script.py 4 -c square
16
在这里,可选参数是有价值的,如果你只是想像标志一样使用它,你也可以。因此,通过将 -s 用于正方形和 -c 用于立方体,我们可以通过添加 action = "store_true" 来改变行为。仅在使用时才更改为 true。
parser.add_argument(
"-s", "--square",
help="returns the square of number",
action="store_true"
)
parser.add_argument(
"-c", "--cube",
help="returns the cube of number",
action="store_true"
)
所以条件块可以更改为,
if args.s:
print("{} is the result".format(args.number**2))
elif args.c:
print("{} is the result".format(args.number**3))
else:
print("{} is not changed".format(args.number))
用法
$python3 script.py 4 -c
64
作为现有答案的补充,如果您足够懒惰,可以使用名为protoargs的代码生成工具。它从配置中生成参数解析器。对于 python,它使用argparse。
带有可选 A 和 B 的配置:
syntax = "proto2";
message protoargs
{
optional string A = 1; // A param description
optional string B = 2; // B param description
}//protoargs
具有所需 A 和 B 的配置:
syntax = "proto2";
message protoargs
{
required string A = 1; // A param description
required string B = 2; // B param description
}//protoargs
位置 A 和 B 的配置:
syntax = "proto2";
message protoargs
{
required string A = 1; // A param description
required string B = 2; // B param description
}//protoargs
message protoargs_links
{
}//protoargs_links
现在你应该运行的是:
python ./protoargs.py -i test.proto -o . --py
并使用它(这里可以举其他例子):
import sys
import test_pa
class ArgsParser:
program = "test"
description = "Simple A and B parser test."
def parse(self, argv):
self.config = test_pa.parse(self.program, self.description, argv)
def usage(self):
return test_pa.usage(self.program, self.description)
if __name__ == "__main__":
parser = ArgsParser()
if len(sys.argv) == 1:
print(parser.usage())
else:
parser.parse(sys.argv[1:])
if parser.config.A:
print(parser.config.A)
if parser.config.B:
print(parser.config.B)
如果您想要更多 - 更改配置,重新生成解析器,使用更新的 parser.config。
UPD:如规则中所述,我必须指定这是我自己的项目
最简单的答案!
PS写argparse文档的人是愚蠢的
蟒蛇代码:
import argparse
parser = argparse.ArgumentParser(description='')
parser.add_argument('--o_dct_fname',type=str)
parser.add_argument('--tp',type=str)
parser.add_argument('--new_res_set',type=int)
args = parser.parse_args()
o_dct_fname = args.o_dct_fname
tp = args.tp
new_res_set = args.new_res_set
运行代码
python produce_result.py --o_dct_fname o_dct --tp father_child --new_res_set 1