这个简化的脚本足以导致问题...只是检查'-d'参数是否是一个有效的目录,如果没有提供默认值,则提供默认值...
#!/usr/bin/python
import os
import argparse
def valid(dir):
subdir = dir + '/Desktop'
if not os.path.exists(subdir):
raise argparse.ArgumentTypeError("%s is not a valid directory" % subdir)
return dir
parser = argparse.ArgumentParser(description="blah blah blah")
parser.add_argument('-d', '--directory', help='directory to check', default=os.getcwd(), type=valid)
args = parser.parse_args()
默认参数是什么并不重要,当我运行脚本时,它使用默认值,无论我在命令行输入什么,并抛出未捕获的异常,如下所示:
Traceback (most recent call last):
File "./parsertest.py", line 15, in <module>
args = parser.parse_args()
File "/usr/lib/python2.7/argparse.py", line 1688, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/usr/lib/python2.7/argparse.py", line 1710, in parse_known_args
default = self._get_value(action, default)
File "/usr/lib/python2.7/argparse.py", line 2239, in _get_value
raise ArgumentError(action, msg)
argparse.ArgumentError: argument -d/--directory: /home/users/jrice/Desktop/Desktop is not a valid directory
运行正常,我的意思是,处理ArgumentTypeError时应该如何,只要我执行以下操作就打印msg:
详细说明:如果我做了上述任何一项,即使'-d'无效,一切都很好。这是输出,这就是我想要的。
>./Desktop/parsertest.py -d blah
usage: parsertest.py [-h] [-d DIRECTORY]
parsertest.py: error: argument -d/--directory: blah/Desktop is not a valid directory
为什么os.getcwd()+'/ Desktop'会有所不同?
答案 0 :(得分:3)
我相信你的“类型检查”过于激进了。您将不存在的目录视为无效类型,这不是argparse
的考虑方式。在您的情况下,默认值可能不是混淆argparse的“有效类型”。查看以下代码及其输出:
#!/usr/bin/python
import os
import argparse
def valid(dir):
print "Checking " + dir
subdir = dir + '/Desktop'
#if not os.path.exists(subdir):
# raise argparse.ArgumentTypeError("%s is not a valid directory" % subdir)
return dir
parser = argparse.ArgumentParser(description="blah blah blah")
parser.add_argument('-d', '--directory', help='directory to check', type=valid, default=os.getcwd())
args = parser.parse_args()
使用/home/user/Desktop
从-d /home/user
执行此操作会发出:
Checking /home/user/Desktop
Checking /home/user
如您所见,argparse
首先转换默认值,然后转换为命令行给定值。
要解决上述问题,请确保默认值始终为“有效类型”,或者在argparse
完成后检查目录。
答案 1 :(得分:2)
Argparse尝试将默认参数转换为赋予它的任何类型。
import argparse
parser = argparse.ArgumentParser(description="blah blah blah")
parser.add_argument('-i',default="1",type=int)
args = parser.parse_args([])
print args # Namespace(i=1)
print type(args.i) # <type 'int'>
这个设计选择的原因对我来说有点奇怪,但可能是这样你可以将字符串传递给default
,就像在命令行上获取它们一样,然后帮助将被正确格式化。
注意我并不喜欢将验证码传递给type
关键字参数,即使它们是在documentation中执行的。该参数是将输入字符串转换为其他类型。如果您真的想在解析时进行验证,则应考虑使用自定义Action
,但对于此示例,它可能只是最简单的方法:
#...snip...
parser.add_argument('-d', '--directory', help='directory to check')
args = parser.parse_args()
args.directory = valid(args.directory if args.directory is not None else os.getcwd())
#the following should work too.
#args.directory = valid(args.directory if args.directory else os.getcwd())