我刚开始使用argparse模块.我编写了以下简化代码片段来演示我遇到的问题.
from argparse import ArgumentParser
if __name__ == '__main__':
parser = ArgumentParser('Test argparse. This string needs to be relatively long to trigger the issue.')
parser.add_argument('-f', '--fin', help='a', required = True)
parser.add_argument('-o', '--out ', help='b', required = True)
parser.add_argument('-t', '--trans', help='c', required = True)
args = parser.parse_args()
print(repr(vars(args)))
Run Code Online (Sandbox Code Playgroud)
AssertionError
将使用参数-h运行脚本时生成
Traceback (most recent call last):
File "arg.py", line 10, in <module>
args = parser.parse_args()
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1707, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1739, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1945, in _parse_known_args
start_index = consume_optional(start_index)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1885, in consume_optional
take_action(action, args, option_string)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1813, in take_action
action(self, namespace, argument_values, option_string)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1017, in __call__
parser.print_help()
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 2341, in print_help
self._print_message(self.format_help(), file)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 2325, in format_help
return formatter.format_help()
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 278, in format_help
help = self._root_section.format_help()
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 208, in format_help
func(*args)
File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 329, in _format_usage
assert ' '.join(opt_parts) == opt_usage
AssertionError
Run Code Online (Sandbox Code Playgroud)
减少传递给ArgumentParser的描述字符串的长度使其正常工作.删除其中一个参数也会有所帮助.
我在这里做错了吗?我的环境是:
Python 3.3.5 | Anaconda 1.9.2(64位)| (默认情况下,2014年3月10日,11:25:04)[winv上的MSC v.1600 64位(AMD64)]
eso*_*ton 11
--out
代码后面有一个额外的空格.更改:
parser.add_argument('-o', '--out ', help='b', required = True)
Run Code Online (Sandbox Code Playgroud)
至:
parser.add_argument('-o', '--out', help='b', required = True)
Run Code Online (Sandbox Code Playgroud)
问题的根本原因是assert
在Python代码中进行检查,这只有在Python试图将帮助文本分成多行时才会发生,因为它太长了.在将文本分成列表之后,Python代码将它连接在一起并将其与原始文件进行比较以确保它是正确的.但是,将文本分开的代码会丢弃相邻的空格,从而导致错误比较.
我在代码中添加了print(argparse.py,Python 2.7):
# wrap the usage parts if it's too long
text_width = self._width - self._current_indent
if len(prefix) + len(usage) > text_width:
# break usage into wrappable parts
part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
opt_usage = format(optionals, groups)
pos_usage = format(positionals, groups)
opt_parts = _re.findall(part_regexp, opt_usage)
pos_parts = _re.findall(part_regexp, pos_usage)
print ' '.join(opt_parts)
print opt_usage
assert ' '.join(opt_parts) == opt_usage
Run Code Online (Sandbox Code Playgroud)
结果如下:
[-h] -f FIN -o OUT -t TRANS
[-h] -f FIN -o OUT -t TRANS
Traceback (most recent call last):
File "blah.py", line 9, in <module>
args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)
注意OUT后的额外空间.
这解释了所有观察到的行为:
--trans
参数移动--out
到最后否定行为.--out
论点否定了behvaior.