我不知道为什么会这样。我的理解是,在执行默认操作之前,用户至少有机会使用-h。
import os, sys, argparse
class argument_parser():
# call on all our file type parsers in the sequence_anlysis_method
def __init__(self):
self.db_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
"""A customized argument parser that does a LOT of error checking"""
self.parser = argparse.ArgumentParser(
prog="igblast")
general = self.parser.add_argument_group(
title="\nGeneral Settings")
general.add_argument(
"-x", '--executable',
default="/usr/bin/igblastn",
type=self._check_if_executable_exists,
help="The location of the executable, default is /usr/bin/igblastn")
self.args = self.parser.parse_args()
def _check_if_executable_exists(self,x_path):
if not os.path.exists(x_path):
msg = "path to executable {0} does not exist, use -h for help\n".format(x_path)
raise argparse.ArgumentTypeError(msg)
if not os.access(x_path, os.R_OK):
msg1 = "executable {0} does have not permission to run\n".format(x_path)
raise argparse.ArgumentTypeError(msg1)
else:
return x_path
if __name__ == '__main__':
argument_class = argument_parser()
现在如果/ usr / bin / igblastn存在,那么它没问题,但如果没有,只需调用此程序就会在self_check_if_executable_exists中引发异常。
File "execution.py", line 220, in <module>
argument_class = ap()
File "/home/willisjr/utilities/pyig/src/arg_parse.py", line 159, in __init__
self.args = self.parser.parse_args()
File "/usr/local/lib/python2.7/argparse.py", line 1656, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/usr/local/lib/python2.7/argparse.py", line 1678, in parse_known_args
default = self._get_value(action, default)
File "/usr/local/lib/python2.7/argparse.py", line 2203, in _get_value
raise ArgumentError(action, msg)
argparse.ArgumentError: argument -x/--executable: path to executable /usr/bin/igblastn does not exist, use -h for help
我的理解是,用户始终有机会运行--help或-h或在采取任何操作之前导致此参数错误。我对arg解析器的理解不清楚吗?
答案 0 :(得分:1)
您忘了在初始__init__
parse_args()
class argument_parser(object):
# call on all our file type parsers in the sequence_anlysis_method
def __init__(self):
self.db_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
"""A customized argument parser that does a LOT of error checking"""
self.parser = argparse.ArgumentParser(
prog="igblast")
general = self.parser.add_argument_group(
title="\nGeneral Settings")
general.add_argument(
"-x", '--executable',
default="/usr/bin/igblastn",
type=self._check_if_executable_exists,
help="The location of the executable, default is /usr/bin/igblastn")
""" >>>>>>>>>>>>> add this line <<<<<<<<<<< """
self.parser.parse_args()
def _check_if_executable_exists(self,x_path):
if not os.path.exists(x_path):
msg = "path to executable {0} does not exist, use -h for help\n".format(x_path)
raise argparse.ArgumentTypeError(msg)
if not os.access(x_path, os.R_OK):
msg1 = "executable {0} does have not permission to run\n".format(x_path)
raise argparse.ArgumentTypeError(msg1)
else:
return x_path
if __name__ == '__main__':
argument_class = argument_parser()
答案 1 :(得分:1)
在Python 2.7.3中,在parse_known_args
的早期(由parse_args
调用),默认值将插入namespace
。
# add any action defaults that aren't present
for action in self._actions:
if action.dest is not SUPPRESS:
if not hasattr(namespace, action.dest):
if action.default is not SUPPRESS:
default = action.default
if isinstance(action.default, basestring): # delayed in 3.3.1
default = self._get_value(action, default)
setattr(namespace, action.dest, default)
如果default
是一个字符串,则会传递_get_value
,在您的案例type
中调用相应的_check_if_executable_exists
。这会产生你看到的错误。
在新闻3.3.1 https://docs.python.org/3.3/whatsnew/changelog.html
中问题#12776,问题#11839:只调用一次argparse类型函数(由add_argument指定)。之前,在指定了默认值并且同时给出了参数的情况下,类型函数被调用了两次。这对于FileType类型尤其有问题,因为即使在命令行上指定了文件参数,也始终会打开默认文件。
通过此更改,_get_value
调用被推迟到parse_known_args
的末尾,并且仅在解析未在其中放置其他值时才会调用(默认值是必需的)。
if isinstance(action.default, basestring): # dropped in 3.3.1
default = self._get_value(action, default)
因此,您的脚本在我的开发副本上按预期运行(使用'-h')。我不完全确定哪个版本的Python有这种更正。
因此,除非您可以运行更新的Python版本,否则您有责任确保default
是有效值。即使有这个错误修复,最好确保默认值有效,然后再将其发送给add_argument()
。无论何时处理,无效的默认设置都会使您的用户感到困惑。