Python 2.7的argparse为您提供了两个扩展点,您可以在其中控制命令行参数的解析方式:键入函数和操作类.
从内置类型和操作开始,最佳实践似乎是类型函数应该包含验证/初始化代码,并且操作应该关注将值存储到命名空间中.这种方法的问题是当你有类型检查代码有副作用.考虑这个简单的例子:
from argparse import ArgumentParser, FileType
argp = ArgumentParser()
argp.add_argument('-o', type=FileType('w'), default='myprog.out')
argp.parse_args(['-o', 'debug.out'])
Run Code Online (Sandbox Code Playgroud)
如果你运行它,你会发现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')
Run Code Online (Sandbox Code Playgroud)
现在尝试使用它:
>>> 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>)
Run Code Online (Sandbox Code Playgroud)
谁下令这种行为?是否有一种理智的方式让默认值的行为与用户传入的完全相同?或者在提供值时不进行类型检查默认值?
据我所知,没有“明智”的方法可以做到这一点。当然,关闭type转换然后对Namespace返回的结果进行后处理是很简单的parse_args:
args = argp.parse_args()
args.o = open(args.o,'w')
Run Code Online (Sandbox Code Playgroud)
但我想那不是你要找的。
| 归档时间: |
|
| 查看次数: |
4813 次 |
| 最近记录: |