使用这个脚本我可以测试提出的替代方案。
import argparse
class ValidateUrl(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values != "bar":
parser.error(f"Please enter a valid. Got: {values}")
setattr(namespace, self.dest, values)
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values != "bar":
print("Got value:", values)
raise argparse.ArgumentError(self, 'Not a bar')
setattr(namespace, self.dest, values)
def database(astring):
if astring != "bar":
raise ValueError('not a bar')
return astring
parser = argparse.ArgumentParser()
parser.add_argument("--url", action=ValidateUrl)
parser.add_argument("--foo", action = FooAction)
parser.add_argument('--data', type = database)
if __name__=='__main__':
args = parser.parse_args()
print(args)
一个实际案例:
1254:~/mypy$ python3 stack37471636.py --url bar --foo bar --data bar
Namespace(data='bar', foo='bar', url='bar')
错误
parser.error
的使用和退出情况。
1255:~/mypy$ python3 stack37471636.py --url xxx
usage: stack37471636.py [-h] [--url URL] [--foo FOO] [--data DATA]
stack37471636.py: error: Please enter a valid. Got: xxx
在 `type` 函数中,`ValueError` 类型的标准错误信息。
1256:~/mypy$ python3 stack37471636.py --data xxx
usage: stack37471636.py [-h] [--url URL] [--foo FOO] [--data DATA]
stack37471636.py: error: argument --data: invalid database value: 'xxx'
使用ArgumentTypeError
,消息将按原样显示:
1246:~/mypy$ python3 stack37471636.py --url bar --foo bar --data xxx
usage: stack37471636.py [-h] [--url URL] [--foo FOO] [--data DATA]
stack37471636.py: error: argument --data: not a bar
FooAction
和 ArgumentError
:
1257:~/mypy$ python3 stack37471636.py --foo xxx
Got value: xxx
usage: stack37471636.py [-h] [--url URL] [--foo FOO] [--data DATA]
stack37471636.py: error: argument --foo: Not a bar
type
中的错误会被转换为 ArgumentError
。请注意,ArgumentError
会标识出相应的 argument
,而调用 parser.error
则不会。
如果 FooAction
引发错误 ValueError
,则会显示正常的回溯信息,但不包括使用情况。
1246:~/mypy$ python3 stack37471636.py --url bar --foo xxx --data bar
Got value: xxx
Traceback (most recent call last):
File "stack37471636.py", line 27, in <module>
args = parser.parse_args()
File "/usr/lib/python3.8/argparse.py", line 1780, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/usr/lib/python3.8/argparse.py", line 1812, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/usr/lib/python3.8/argparse.py", line 2018, in _parse_known_args
start_index = consume_optional(start_index)
File "/usr/lib/python3.8/argparse.py", line 1958, in consume_optional
take_action(action, args, option_string)
File "/usr/lib/python3.8/argparse.py", line 1886, in take_action
action(self, namespace, argument_values, option_string)
File "stack37471636.py", line 13, in __call__
raise ValueError("Not a bar!")
ValueError: Not a bar!
我认为ArgumentError
和ArgumentTypeError
是首选,或者至少是意图选择。自动生成的错误会使用这些。
通常在解析后使用parser.error
,例如:
1301:~/mypy$ python3 stack37471636.py
Namespace(data=None, foo=None, url=None)
usage: stack37471636.py [-h] [--url URL] [--foo FOO] [--data DATA]
stack37471636.py: error: not a bar