Python argparse断言错误
我刚开始使用argparse模块。我编写了以下简化的代码片段来演示我遇到的一个问题Python argparse断言错误,python,argparse,Python,Argparse,我刚开始使用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
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)))
使用参数-h运行脚本时将生成AssertionError
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
回溯(最近一次呼叫最后一次):
文件“arg.py”,第10行,在
args=parser.parse_args()
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1707行,在parse\u args中
args,argv=self.parse\u known\u args(args,名称空间)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1739行,位于parse\u known\u args中
名称空间,args=self.\u解析\u已知\u args(args,名称空间)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1945行,在_parse\u known\u args中
开始索引=消耗索引可选(开始索引)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1885行,在consume\u optional中
执行操作(操作、参数、选项字符串)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1813行,在take\u action中
操作(自身、名称空间、参数值、选项字符串)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1017行,在调用中__
parser.print_help()
打印帮助中的文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第2341行
self.\u打印消息(self.format\u help(),文件)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第2325行,格式为\u help
返回格式化程序。格式化\u帮助()
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第278行,格式为\u help
help=self.\u root\u section.format\u help()
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第208行,格式为\u help
func(*args)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第329行,格式为
断言“”。连接(opt_部分)=opt_用法
断言错误
减少传递给ArgumentParser的描述字符串的长度可以使其正常工作。删除其中一个参数也会有所帮助
我做错什么了吗?我的环境是:
Python 3.3.5 | Anaconda 1.9.2(64位)|(默认,2014年3月10日),
win32上的11:25:04)[MSC v.1600 64位(AMD64)]
代码中的
--out
后面有一个额外的空格。更改:
parser.add_argument('-o', '--out ', help='b', required = True)
致:
问题的根本原因是Python中的assert
检查
仅当Python尝试将帮助文本拆分为
多行,因为太长。将文本拆分为列表后,
Python代码将其重新连接在一起,并将其与原始代码进行比较
确保它是正确的。但是,将文本分开的代码会丢失
导致错误比较的相邻空间
我在代码中添加了打印(argparse.py,Python 2.7):
结果是:
[-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()
[-h]-f FIN-o OUT-t TRANS
[-h]-f FIN-o OUT-t变速器
回溯(最近一次呼叫最后一次):
文件“blah.py”,第9行,在
args=parser.parse_args()
注意输出后的额外空间
这解释了所有观察到的行为:
- 必须足够长才能触发包裹行为
- 删除
参数将--trans
移动到否定行为的末尾--out
- 删除
参数否定了behvaior--out
- 问题不在于您添加的额外-h。查看错误和
-o
参数:
assert ' '.join(opt_parts) == opt_usage
它在
'--out'
中加入空格。如果删除它,一切都会正常工作。我来到这里时遇到了完全相同的问题/错误,但在--out
之后没有任何额外的空格。我的问题是metavar被设置为空字符串(metavar='
)。更改解决了问题。Python 3.5.2
这让我疯狂了一段时间,但我终于发现了问题所在。
这肯定是一个使用行长度问题,如果它超过了为控制台/终端设置的COLUMNS
环境变量,则会出现该错误。
我尝试从命令行执行以下操作:
$COLUMNS=80 python-h
我得到一个例外:
...
File "/usr/lib/python3.5/argparse.py", line 1735, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/usr/lib/python3.5/argparse.py", line 1767, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/usr/lib/python3.5/argparse.py", line 1973, in _parse_known_args
start_index = consume_optional(start_index)
File "/usr/lib/python3.5/argparse.py", line 1913, in consume_optional
take_action(action, args, option_string)
File "/usr/lib/python3.5/argparse.py", line 1841, in take_action
action(self, namespace, argument_values, option_string)
File "/usr/lib/python3.5/argparse.py", line 1025, in __call__
parser.print_help()
File "/usr/lib/python3.5/argparse.py", line 2367, in print_help
self._print_message(self.format_help(), file)
File "/usr/lib/python3.5/argparse.py", line 2351, in format_help
return formatter.format_help()
File "/usr/lib/python3.5/argparse.py", line 287, in format_help
help = self._root_section.format_help()
File "/usr/lib/python3.5/argparse.py", line 217, in format_help
func(*args)
File "/usr/lib/python3.5/argparse.py", line 338, in _format_usage
assert ' '.join(opt_parts) == opt_usage
AssertionError
但是:
$COLUMNS=python-h
其中XX>的结果用法行,一切正常,它打印用法+帮助并退出。
因此,要么缩短使用行,要么增加列
值
编辑:
我在案例中发现了错误:我在程序/参数描述中使用了方括号[]
正如其他人正确指出的那样,查看发生异常的python代码,您可以看到argparse有一个自动将用法/帮助折叠到$COLUMNS
COLUMNS的规定。
但要拆分长行,它将使用以下RE:
(文件“/usr/lib/python3.5/argparse.py”,第333行:)
当它重新加入行以进行检查时,如果用户引入了方括号,则断言失败,因为它们是argparse用来标记可选值的特殊字符
简而言之,我从文本中删除了rogue方括号,一切正常,用法/帮助根据
$COLUMNS
值正确折叠和格式化。对我来说,它同时设置了required=True和metavar=''。删除一个并保留另一个解决了这个问题。请记住,ArgumentParser.\uuuu init\uuuu
实际上并不接受位置参数。给定关键字参数的定义顺序,您将传递一个非常长的字符串来初始化prog
属性,该属性用于存储出现在帮助消息中的程序名。您试图用该字符串初始化哪个属性?部分问题在于您不是sp
assert ' '.join(opt_parts) == opt_usage
...
File "/usr/lib/python3.5/argparse.py", line 1735, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/usr/lib/python3.5/argparse.py", line 1767, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/usr/lib/python3.5/argparse.py", line 1973, in _parse_known_args
start_index = consume_optional(start_index)
File "/usr/lib/python3.5/argparse.py", line 1913, in consume_optional
take_action(action, args, option_string)
File "/usr/lib/python3.5/argparse.py", line 1841, in take_action
action(self, namespace, argument_values, option_string)
File "/usr/lib/python3.5/argparse.py", line 1025, in __call__
parser.print_help()
File "/usr/lib/python3.5/argparse.py", line 2367, in print_help
self._print_message(self.format_help(), file)
File "/usr/lib/python3.5/argparse.py", line 2351, in format_help
return formatter.format_help()
File "/usr/lib/python3.5/argparse.py", line 287, in format_help
help = self._root_section.format_help()
File "/usr/lib/python3.5/argparse.py", line 217, in format_help
func(*args)
File "/usr/lib/python3.5/argparse.py", line 338, in _format_usage
assert ' '.join(opt_parts) == opt_usage
AssertionError
`part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'`