Python argparse 检查类型前的选择
Python argparse check choices before type
我正在尝试使用户能够传入函数名称。出于某种原因,argparse 似乎在检查选择之前执行类型 check/conversion。这是一个错误吗?最好的事情是什么?
import argparse
def foo():
return 'foo'
def bar():
return 'bar'
parser = argparse.ArgumentParser()
functions = {f.__name__:f for f in [foo, bar]}
parser.add_argument("function", type=lambda f: functions.get(f), help="which function", choices=functions)
args = parser.parse_args()
print(args.function())
这抛出:
$ python blah.py foo
usage: blah.py [-h] {foo,bar}
blah.py: error: argument function: invalid choice: <function foo at 0x7f65746dd848> (choose from 'foo', 'bar')
显然是这样,但是您可以通过使用 functions.keys()
作为您的选择来解决这个问题,例如
import argparse
def foo():
return 'foo'
def bar():
return 'bar'
parser = argparse.ArgumentParser()
functions = {f.__name__:f for f in [foo, bar]}
parser.add_argument("function", type=lambda f: functions.get(f), help="which function", choices=functions.values())
args = parser.parse_args()
print(args.function())
但是,如果您想提供这种接口(将函数映射到命令行参数),您可能需要查看 click。
是的,在解析 type
then choices
的过程中,顺序是明确且有意的(而不仅仅是偶然的)。在准备将 arg_strings
分配给 namespace
时,它会调用 _get_values
,它会:
def _get_values(self, action, arg_strings)
.... (various nargs tests)
value = self._get_value(action, arg_string)
self._check_value(action, value)
return value
其中 _get_value
应用 action.type
函数,_check_value
测试
value not in action.choices
解析 choices
只需响应 in
(__contains__
) 表达式。
所以choices
必须反映转换后的值。如果type
是int
,那么choices=[1,2,3]
是正确的,['1','2','3']
是错误的。
选项的显示存在一些(大部分未解决的)错误问题。长列表,例如range(100)
可以解析,但显示效果不佳。并且显示还要求 choices
是可迭代的(例如列表、元组、字典)。此显示问题会影响使用、帮助和错误消息(每种格式 choices
略有不同)。
metavar
是替换不需要的 choices
列表的最强大工具。我必须 运行 一个测试用例,看看它是否能解决所有 3 种情况。
我正在尝试使用户能够传入函数名称。出于某种原因,argparse 似乎在检查选择之前执行类型 check/conversion。这是一个错误吗?最好的事情是什么?
import argparse
def foo():
return 'foo'
def bar():
return 'bar'
parser = argparse.ArgumentParser()
functions = {f.__name__:f for f in [foo, bar]}
parser.add_argument("function", type=lambda f: functions.get(f), help="which function", choices=functions)
args = parser.parse_args()
print(args.function())
这抛出:
$ python blah.py foo
usage: blah.py [-h] {foo,bar}
blah.py: error: argument function: invalid choice: <function foo at 0x7f65746dd848> (choose from 'foo', 'bar')
显然是这样,但是您可以通过使用 functions.keys()
作为您的选择来解决这个问题,例如
import argparse
def foo():
return 'foo'
def bar():
return 'bar'
parser = argparse.ArgumentParser()
functions = {f.__name__:f for f in [foo, bar]}
parser.add_argument("function", type=lambda f: functions.get(f), help="which function", choices=functions.values())
args = parser.parse_args()
print(args.function())
但是,如果您想提供这种接口(将函数映射到命令行参数),您可能需要查看 click。
是的,在解析 type
then choices
的过程中,顺序是明确且有意的(而不仅仅是偶然的)。在准备将 arg_strings
分配给 namespace
时,它会调用 _get_values
,它会:
def _get_values(self, action, arg_strings)
.... (various nargs tests)
value = self._get_value(action, arg_string)
self._check_value(action, value)
return value
其中 _get_value
应用 action.type
函数,_check_value
测试
value not in action.choices
解析 choices
只需响应 in
(__contains__
) 表达式。
所以choices
必须反映转换后的值。如果type
是int
,那么choices=[1,2,3]
是正确的,['1','2','3']
是错误的。
选项的显示存在一些(大部分未解决的)错误问题。长列表,例如range(100)
可以解析,但显示效果不佳。并且显示还要求 choices
是可迭代的(例如列表、元组、字典)。此显示问题会影响使用、帮助和错误消息(每种格式 choices
略有不同)。
metavar
是替换不需要的 choices
列表的最强大工具。我必须 运行 一个测试用例,看看它是否能解决所有 3 种情况。