可以argparse
用于验证文件名cmd行参数的文件扩展名吗?
e.g。如果我有一个python脚本我从cmd行运行:
$ script.py file.csv
$ script.py file.tab
$ script.py file.txt
我希望argparse接受前两个文件名cmd行选项,但拒绝第三个
我知道你可以这样做:
parser = argparse.ArgumentParser()
parser.add_argument("fn", choices=["csv","tab"])
args = parser.parse_args()
为cmd行选项指定两个有效选项
我想要的是:
parser.add_argument("fn", choices=["*.csv","*.tab"])
为cmd行选项指定两个有效的文件扩展名。不幸的是,这不起作用 - 是否有办法使用argparse
实现此目的?
答案 0 :(得分:8)
当然 - 您只需要指定一个适当的函数type
。
import argparse
import os.path
parser = argparse.ArgumentParser()
def file_choices(choices,fname):
ext = os.path.splitext(fname)[1][1:]
if ext not in choices:
parser.error("file doesn't end with one of {}".format(choices))
return fname
parser.add_argument('fn',type=lambda s:file_choices(("csv","tab"),s))
parser.parse_args()
演示:
temp $ python test.py test.csv
temp $ python test.py test.foo
usage: test.py [-h] fn
test.py: error: file doesn't end with one of ('csv', 'tab')
这可能是更干净/更通用的方法:
import argparse
import os.path
def CheckExt(choices):
class Act(argparse.Action):
def __call__(self,parser,namespace,fname,option_string=None):
ext = os.path.splitext(fname)[1][1:]
if ext not in choices:
option_string = '({})'.format(option_string) if option_string else ''
parser.error("file doesn't end with one of {}{}".format(choices,option_string))
else:
setattr(namespace,self.dest,fname)
return Act
parser = argparse.ArgumentParser()
parser.add_argument('fn',action=CheckExt({'csv','txt'}))
print parser.parse_args()
这里的缺点是代码在某些方面变得有点复杂 - 结果是当你真正去格式化你的参数时,界面会变得更清晰。
答案 1 :(得分:4)
定义一个自定义函数,它将名称作为字符串 - 将扩展名拆分以进行比较,如果没有问题则返回字符串,否则引发argparse期望的异常:
def valid_file(param):
base, ext = os.path.splitext(param)
if ext.lower() not in ('.csv', '.tab'):
raise argparse.ArgumentTypeError('File must have a csv or tab extension')
return param
然后使用该功能,例如:
parser = argparse.ArgumentParser()
parser.add_argument('filename', type=valid_file)
答案 2 :(得分:-1)
没有。您可以为choices参数或支持“in”运算符的任何内容提供容器对象。您可以在pydocs
了解更多信息您可以随时自行查看并向用户提供反馈。