Python 2.7&#arsparse为您提供了两个扩展点,您可以在其中控制命令行参数的解析方式:键入函数和操作类。
从内置类型和操作开始,最佳实践似乎是类型函数应该包含验证/初始化代码,并且操作应该关注将值存储到命名空间中。这种方法的问题是当你有类型检查代码有副作用。考虑这个简单的例子:
from argparse import ArgumentParser, FileType
argp = ArgumentParser()
argp.add_argument('-o', type=FileType('w'), default='myprog.out')
argp.parse_args(['-o', 'debug.out'])
如果你运行它,你会发现python会在系统myprog.out
和debug.out
上打开两个文件。当用户没有提供debug.out
参数时,仅打开-o
会更有意义。
稍微调整一下,似乎argparse只会在传递的参数或str类型的默认参数上调用你的类型函数。如果你的类型检查器有副作用,这是很不幸的,因为即使传递了一个值,它也会在默认情况下被调用。因此,对于带有副作用的初始化,也许最好在动作中执行此操作。这样做的问题是,如果您提供默认值,则不会调用该操作!
请考虑以下代码:
from argparse import ArgumentParser, Action
def mytype(arg):
print 'checking type for ' + repr(arg)
return arg
class OutputFileAction(Action):
def __call__(self, parser, namespace, values, option_string=None):
print 'running action for ' + repr(values)
try:
outstream = open(values, 'w')
except IOError as e:
raise ArgumentError('error opening file ' + values)
setattr(namespace, self.dest, outstream)
argp = ArgumentParser()
argp.add_argument('-o', type=mytype, action=OutputFileAction, default='myprog.out')
现在尝试使用它:
>>> argp.parse_args([])
checking type for 'myprog.out'
Namespace(o='myprog.out')
>>> argp.parse_args(['-o', 'debug.out'])
checking type for 'myprog.out'
checking type for 'debug.out'
running action for 'debug.out'
Namespace(o=<open file 'debug.out', mode 'w' at 0x2b7fced07300>)
谁订购了 行为?是否有一种理智的方式让默认值的行为与用户传入的完全相同?或者在提供值时不进行类型检查默认值?
答案 0 :(得分:2)
据我所知,没有“明智”的方法可以做到这一点。当然,关闭type
转换然后对从Namespace
返回的parse_args
进行后处理是微不足道的:
args = argp.parse_args()
args.o = open(args.o,'w')
但我想这不是你想要的。