在解析参数时使用argparse模块添加验证是否可行?
from argparse import ArgumentParser
parser = ArgumentParser(description='Argument parser for PG restore')
parser.add_argument('--database', dest='database',
default=None, required=False, help='Database to restore')
parser.add_argument('--backup', dest='backup',
required=True, help='Location of the backup file')
parsed_args = parser.parse_args()
是否可以在此参数解析器中添加验证检查,以确保备份文件/数据库存在?而不是必须在此之后为每个参数添加额外的检查,例如:
from os.path import exists
if not database_exists(parsed_args.database):
raise DatabaseNotFoundError
if not exists(parsed_args.backup):
raise FileNotFoundError
答案 0 :(得分:14)
argparse.FileType
是一个可以打开文件的type
工厂类,当然,如果文件不存在或无法创建,则会在此过程中引发错误。您可以查看其代码,了解如何创建自己的类(或函数)来测试输入。
参数type
参数是一个可调用的(函数等),它接受一个字符串,根据需要对其进行测试,并将其(根据需要)转换为您想要保存到{{1命名空间。所以它可以做任何你想要的测试。如果args
引发错误,则解析器会创建错误消息(和使用情况)并退出。
现在是否适合进行测试取决于您的情况。有时用type
打开文件很好,但是你必须自己关闭它,或者等待程序结束。您无法在FileType
上下文中使用该打开文件。这同样适用于您的数据库。在复杂的程序中,您可能不想立即打开或创建文件。
我写了一篇关于Python错误/问题的with open(filename) as f:
的变体,它创建了一个FileType
,一个可以在context
上下文中使用的对象。我还使用with
测试来检查文件是否存在或是否可以创建,而实际上并没有这样做。但如果os
为file
您不想关闭,则需要进一步的操作。有时候尝试在stdin/out
中做这样的事情只是工作而不是它的价值。
无论如何,如果你有一个简单的测试方法,你可以将它包装在一个简单的argparse
函数中,如下所示:
type
我认为在def database(astring):
from os.path import exists
if not database_exists(astring):
raise ValueError # or TypeError, or `argparse.ArgumentTypeError
return astring
parser.add_argument('--database', dest='database',
type = database,
default=None, required=False, help='Database to restore')
或type
中实施这样的测试并不重要。我认为Action
更简单,更符合开发人员的意图。
答案 1 :(得分:12)
当然!您只需将自定义操作指定为类,并覆盖__call__(..)
。 Link to documentation.
类似的东西:
import argparse
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values != "bar":
print "Got value:", values
raise ValueError("Not a bar!")
setattr(namespace, self.dest, values)
parser = argparse.ArgumentParser()
parser.add_argument("--foo", action=FooAction)
parsed_args = parser.parse_args()
在您的特定情况下,我认为您有DatabaseAction
和FileAction
(或类似的东西)。