定义不同形式的 argparse 参数输入
Defining different forms of argparse argument inputs
我刚开始使用 argparse
,我的代码可以工作,但我正在尝试根据用户在参数中的输入方式解析不同的值。
目前这是我的代码:
def setup_args():
"""
Set up args for the tool
"""
parser = argparse.ArgumentParser(
description=("Get all file versions of a status in a project"),
formatter_class=argparse.RawDescriptionHelpFormatter)
# Positional Arguments
parser.add_argument('project',
type=str,
help='Name of the to look into')
parser.add_argument('status',
type=str,
help='Define which status to look into')
# Optional Arguments
parser.add_argument('-o',
'--output',
action='store_true',
help='Write to output to text file if used')
if __name__ == "__main__":
args = setup_args()
# Check the status set
status_list = ['Pending', 'Work in Progress', 'Approved', 'Rejected']
if not args.status in site_list:
raise ValueError("Please input one of the status : 'Pending', 'Work in Progress', 'Approved', 'Rejected'")
output_query(args.project, status, args.client, args.output)
正如你在我的main
..中看到的那样,它只注册那些我定义的区分大小写的状态名称。
如果代码以小型大写字母输入 - 'pending', 'work in progress', 'approved', 'rejected'
或缩写形式 - 'p', 'wip', 'a', 'r'
?
是否有任何方法可以使我的代码注册
我可以实现的方法之一是使用 if..elif..
if args.client == ('pending' or 'p'):
args.client = 'Pending'
elif args.client == ('work in progress' or 'wip'):
args.client = 'Work in Progress'
elif args.client == ('approved' or 'a'):
args.client = 'Approved'
elif args.client == ('rejected' or 'r'):
args.client = 'Rejected'
虽然有效,但对我来说有点 'long-winded'。如果我有多个参数,这意味着我需要输入很多 if...elif...
,除非这是唯一的方法,否则这可能不切实际。
有没有更好的解决方案来解决这个问题?
编辑:
我就是这样 运行 我的命令:python prog.py my_project Pending
但我正在考虑可以这样输入的场景:python prog.py my_project pending
或 python prog.py my_project p
,请注意大写字母 P 已变成小写字母..
虽然我没有测试过,但查看 add_argument
函数文档,您应该可以将它们添加为它的第一个参数。
name or flags - Either a name or a list of option strings, e.g. foo or -f, --foo.
https://docs.python.org/3/library/argparse.html#the-add-argument-method
您可以将 status
检查概括为 .lower()
并限制您检查的字符数。
例如,如果我定义一个 'choices' 的缩写列表,我可以测试任何看起来像大牌的东西:
In [239]: choices = ['pend', 'work', 'appr','reje']
In [240]: status_list = ['Pending', 'Work in Progress', 'Approved', 'Rejected']
In [241]: for wd in status_list:
...: if wd.lower()[:4] in choices:
...: print(wd)
...:
Pending
Work in Progress
Approved
Rejected
您可能不应该期望您的用户输入完整的 'Work in Progress' 字符串。这样做需要引用。否则 shell 会将其分成 3 个字符串。
此测试的变体使用 startswith
:
for wd in status_list:
if any([wd.lower().startswith(n) for n in choices]):
print(wd)
您也可以让解析器进行值检查
parser.add_argument('status',
# type=str, # default, don't need to add it
choices = ['pending', 'work', 'approved', 'rejected'],
help='Define which status to look into')
如果字符串不匹配,则会生成一条很好的错误消息。并将选项合并到帮助中。试一试,看看会发生什么。
缺点是不允许缩写或upper/lower大小写。 (自定义 type
函数可以绕过这些限制,但这是一种更高级的技术)。
==================
一种使用type
的方法是定义一个小函数:
def abrev(astr):
return astr.lower()[:4]
在上面的测试中有效:
for wd in status_list:
if abrev(wd) in choices:
print(wd)
在解析器中它可以用作:
In [253]: p = argparse.ArgumentParser()
In [254]: p.add_argument('status', type=abrev, choices=choices);
In [255]: p.print_help()
usage: ipython3 [-h] {pend,work,appr,reje}
positional arguments:
{pend,work,appr,reje}
optional arguments:
-h, --help show this help message and exit
调用示例:
In [256]: p.parse_args(['Work'])
Out[256]: Namespace(status='work')
In [257]: p.parse_args(['status'])
usage: ipython3 [-h] {pend,work,appr,reje}
ipython3: error: argument status: invalid choice: 'stat' (choose from 'pend', 'work', 'appr', 'reje')
...
In [258]: p.parse_args(['reject'])
Out[258]: Namespace(status='reje')
In [259]: p.parse_args(['Pending'])
Out[259]: Namespace(status='pend')
我刚开始使用 argparse
,我的代码可以工作,但我正在尝试根据用户在参数中的输入方式解析不同的值。
目前这是我的代码:
def setup_args():
"""
Set up args for the tool
"""
parser = argparse.ArgumentParser(
description=("Get all file versions of a status in a project"),
formatter_class=argparse.RawDescriptionHelpFormatter)
# Positional Arguments
parser.add_argument('project',
type=str,
help='Name of the to look into')
parser.add_argument('status',
type=str,
help='Define which status to look into')
# Optional Arguments
parser.add_argument('-o',
'--output',
action='store_true',
help='Write to output to text file if used')
if __name__ == "__main__":
args = setup_args()
# Check the status set
status_list = ['Pending', 'Work in Progress', 'Approved', 'Rejected']
if not args.status in site_list:
raise ValueError("Please input one of the status : 'Pending', 'Work in Progress', 'Approved', 'Rejected'")
output_query(args.project, status, args.client, args.output)
正如你在我的main
..中看到的那样,它只注册那些我定义的区分大小写的状态名称。
如果代码以小型大写字母输入 - 'pending', 'work in progress', 'approved', 'rejected'
或缩写形式 - 'p', 'wip', 'a', 'r'
?
我可以实现的方法之一是使用 if..elif..
if args.client == ('pending' or 'p'):
args.client = 'Pending'
elif args.client == ('work in progress' or 'wip'):
args.client = 'Work in Progress'
elif args.client == ('approved' or 'a'):
args.client = 'Approved'
elif args.client == ('rejected' or 'r'):
args.client = 'Rejected'
虽然有效,但对我来说有点 'long-winded'。如果我有多个参数,这意味着我需要输入很多 if...elif...
,除非这是唯一的方法,否则这可能不切实际。
有没有更好的解决方案来解决这个问题?
编辑:
我就是这样 运行 我的命令:python prog.py my_project Pending
但我正在考虑可以这样输入的场景:python prog.py my_project pending
或 python prog.py my_project p
,请注意大写字母 P 已变成小写字母..
虽然我没有测试过,但查看 add_argument
函数文档,您应该可以将它们添加为它的第一个参数。
name or flags - Either a name or a list of option strings, e.g. foo or -f, --foo.
https://docs.python.org/3/library/argparse.html#the-add-argument-method
您可以将 status
检查概括为 .lower()
并限制您检查的字符数。
例如,如果我定义一个 'choices' 的缩写列表,我可以测试任何看起来像大牌的东西:
In [239]: choices = ['pend', 'work', 'appr','reje']
In [240]: status_list = ['Pending', 'Work in Progress', 'Approved', 'Rejected']
In [241]: for wd in status_list:
...: if wd.lower()[:4] in choices:
...: print(wd)
...:
Pending
Work in Progress
Approved
Rejected
您可能不应该期望您的用户输入完整的 'Work in Progress' 字符串。这样做需要引用。否则 shell 会将其分成 3 个字符串。
此测试的变体使用 startswith
:
for wd in status_list:
if any([wd.lower().startswith(n) for n in choices]):
print(wd)
您也可以让解析器进行值检查
parser.add_argument('status',
# type=str, # default, don't need to add it
choices = ['pending', 'work', 'approved', 'rejected'],
help='Define which status to look into')
如果字符串不匹配,则会生成一条很好的错误消息。并将选项合并到帮助中。试一试,看看会发生什么。
缺点是不允许缩写或upper/lower大小写。 (自定义 type
函数可以绕过这些限制,但这是一种更高级的技术)。
==================
一种使用type
的方法是定义一个小函数:
def abrev(astr):
return astr.lower()[:4]
在上面的测试中有效:
for wd in status_list:
if abrev(wd) in choices:
print(wd)
在解析器中它可以用作:
In [253]: p = argparse.ArgumentParser()
In [254]: p.add_argument('status', type=abrev, choices=choices);
In [255]: p.print_help()
usage: ipython3 [-h] {pend,work,appr,reje}
positional arguments:
{pend,work,appr,reje}
optional arguments:
-h, --help show this help message and exit
调用示例:
In [256]: p.parse_args(['Work'])
Out[256]: Namespace(status='work')
In [257]: p.parse_args(['status'])
usage: ipython3 [-h] {pend,work,appr,reje}
ipython3: error: argument status: invalid choice: 'stat' (choose from 'pend', 'work', 'appr', 'reje')
...
In [258]: p.parse_args(['reject'])
Out[258]: Namespace(status='reje')
In [259]: p.parse_args(['Pending'])
Out[259]: Namespace(status='pend')