python - argparse and custom Actions - code path not obvious
问题描述
I'm using argparse to digest text commands rather than trying to roll my own custom parser, but the code path is not obvious. Consider the following:
import argparse
##class ReadAction(argparse.Action):
## def __init__(self, option_strings, dest, nargs=None, **kwargs):
## if nargs is not None:
## raise ValueError("nargs not allowed")
## super(ReadAction, self).__init__(option_strings, dest, **kwargs)
## def __call__(self, parser, namespace, values, option_strings=None):
## print("Read a file")
## setattr(namespace, self.dest, values)
class ExitAction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
super(ExitAction, self).__init__(option_strings, dest, **kwargs)
def __call__(self, parser, namespace, values, option_strings=None):
print("Exiting the program")
setattr(namespace, self.dest, values)
def setup_parser(parser):
## parser.add_argument('read', help='Reads in a file', action=ReadAction)
parser.add_argument('exit', help='Exit command', action=ExitAction)
def run():
parser = argparse.ArgumentParser()
setup_parser(parser)
while True:
raw_input = input("Command >>>").split(' ')
args = parser.parse_args(raw_input)
print(args)
print('Good bye')
if __name__ == '__main__':
run()
If I run it as is, I get the expected output:
Command >>>exit
Exiting the program
Namespace(exit='exit')
But if I take out the comments and run again, I get this unexpected behavior:
Command >>>exit
Read a file
usage: prog.py [-h] read exit
prog.py: error: the following arguments are required: exit
Does anyone understand the code path through this? It's like the __call__ method isn't being called (ironic).
解决方案
You aren't binding commands to the literal strings read
and exit
; that's not how argparse
works. Instead, you are defining a parser that takes two arbitrary words, and binds the first to read
and the second to exit
. Your commented code would exit no matter what single word you typed, not just exit
. Without the comments, the parser expects two words, and raises an error when you only provide one.
If you are going to (ab)use argparse
in this fashion, I suggest you read up on subcommands in the documentation.
推荐阅读
- android - 重置 onActivityResult 中的值
- css - css类中的垂直线
- python - 使用 Beautifulsoup 查找特定 ID 下的文章
- flutter - 为什么 Navigator.pop 无法传回参数?
- python - matplotlib 中 yticks/xticks 函数的刻度参数到底是什么?
- xml - 如何使用selenium java同时打开两个浏览器
- dictionary - Dart Map.removeWhere 不删除所有匹配删除条件的键
- c - 在 Visual Studio 代码中将“{”设置为接近结尾的“)”
- javascript - JavaScript使用For循环加载多个图像不起作用
- android - 协助 android studio gradle