1

my application uses a database, so when adding a new element (from command line) I want to check if this one is already in the database, what I do with the "type" parameter of add_argument:

def check_uniq(project_name):
    if Project.exists(project_name):
        raise argparse.ArgumentTypeError(
    return project_name

this is working just fine, however to make think easier to the final user I'd like to add a --force option to my arguments so this variable is tested and delete before to add and in this case do note raise the argument. How can I access within the check_uniq to the --force option ?

4

2 回答 2

2

测试选项是否设置在同一个if语句中:

def check_uniq(project_name, options):
    if Project.exists(project_name) and not options.force:
        raise argparse.ArgumentTypeError('Project already exists')
    return project_name

whereoptions获取由 .Namespace返回的实例parser.parse_args()

不幸的是,在所有参数都被解析之前,您无法验证这一点,您不能将此函数用作type参数,因为该--force选项可以在命令行上的任何位置指定,在指定项目名称的选项之前之后。

如果您需要在命令行上的任何项目之前--force列出它,则可以使用自定义;到目前为止,已将自定义操作传递给已解析的对象:actionnamespace

class UniqueProjectAction(argparse.Action):
    def __call__(self, parser, namespace, value, option_string=None):
        if Project.exists(value) and not namespace.force:
            raise argparse.ArgumentTypeError('Project already exists')
        setattr(namespace, self.dest, values)
于 2013-09-06T11:52:54.350 回答
1

type函数的目的是将参数字符串转换为其他类型的对象(int, float, file)。它无权访问namespace解析器的 或其他属性。间接地,它可以访问全局状态,例如尝试在FileType.

action可以访问,但通常这namespace是为了设置值(属性)。它可以检查其他属性的值,但这最终会限制属性设置的顺序(例如--force必须在之前database)。

您还可以namespace在 之后检查属性parse_args。您仍然可以argparse通过调用来使用错误机制parser.error('your message')。在这个阶段检查值可能更容易,因为您不必担心sys.argv.

于 2013-09-06T16:35:58.213 回答