Python:参数解析验证最佳实践 [英] Python: Argument Parsing Validation Best Practices
问题描述
在解析参数时使用argparse模块是否可以添加验证?
Is it possible when using the argparse module to add validation when parsing arguments?
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()
是否可以向此参数解析器添加验证检查,以确保备份文件/数据库存在?不必在此之后为每个参数添加额外的检查,例如:
Would it be possible, to add a validation check to this argument parser, to make sure the backup file / database exist? Rather than having to add an extra check after this for every parameter such as:
from os.path import exists
if not database_exists(parsed_args.database):
raise DatabaseNotFoundError
if not exists(parsed_args.backup):
raise FileNotFoundError
推荐答案
argparse.FileType
是一个可以打开文件的 type
工厂类,当然,如果文件不存在或无法创建,则在此过程中会引发错误.您可以查看其代码以了解如何创建您自己的类(或函数)来测试您的输入.
The argparse.FileType
is a type
factory class that can open a file, and of course, in the process raise an error if the file does not exist or cannot be created. You could look at its code to see how to create your own class (or function) to test your inputs.
argument type
参数是一个可调用的(函数等),它接受一个字符串,根据需要对其进行测试,然后将它(根据需要)转换为您想要保存到args
命名空间.所以它可以做任何你想做的测试.如果 type
引发错误,则解析器会创建错误消息(和用法)并退出.
The argument type
parameter is a callable (function, etc) that takes a string, tests it as needed, and converts it (as needed) into the kind of value you want to save to the args
namespace. So it can do any kind of testing you want. If the type
raises an error, then the parser creates an error message (and usage) and exits.
现在是否适合进行测试取决于您的情况.有时用 FileType
打开文件没问题,但是你必须自己关闭它,或者等待程序结束.您不能在 with open(filename) as f:
上下文中使用该打开的文件.这同样适用于您的数据库.在复杂的程序中,您可能不想立即打开或创建文件.
Now whether that's the right place to do the testing or not depends on your situation. Sometimes opening a file with FileType
is fine, but then you have to close it yourself, or wait for the program to end. You can't use that open file in a with open(filename) as f:
context. The same could apply to your database. In a complex program you may not want to open or create the file right away.
我为一个 Python 错误/问题编写了 FileType
的一个变体,它创建了一个 context
,一个可以在 with
中使用的对象语境.我还使用 os
测试来检查文件是否存在或可以创建,但实际上并没有这样做.但是,如果 file
是您不想关闭的 stdin/out
,则需要进一步的技巧.有时尝试在 argparse
中做这样的事情只是比它的价值更多的工作.
I wrote for a Python bug/issue a variation on FileType
that created a context
, an object that could be used in the with
context. I also used os
tests to check if the file existed or could be created, without actually doing so. But it required further tricks if the file
was stdin/out
that you don't want to close. Sometimes trying to do things like this in argparse
is just more work than it's worth.
无论如何,如果你有一个简单的测试方法,你可以把它包装在一个简单的 type
函数中,如下所示:
Anyways, if you have an easy testing method, you could wrap it in a simple type
function like this:
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
中实现这样的测试并不重要.我觉得type
更简单,更符合开发者的意图.
I don't think it matters a whole lot whether you implement testing like this in the type
or Action
. I think the type
is simpler and more in line with the developer's intentions.
这篇关于Python:参数解析验证最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!