Argparse - accessing multiple arguments at once

不想你离开。 提交于 2019-12-11 09:03:46

问题


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 ?


回答1:


Test if the option is set in the same if stamement:

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

where options takes the Namespace instance returned by parser.parse_args().

Unfortunately, you cannot verify this until all arguments have been parsed, you cannot use this function as a type parameter, because the --force option can be specified anywhere on the command line, before or after the option that specifies your project name.

If you require that --force is listed before any projects on your command line, you could use a custom action instead; a custom action is passed the namespace object as parsed so far:

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)



回答2:


The purpose of the type function is to convert an argument string to some other kind of object (int, float, file). It does not have access to the namespace or other attributes of the parser. Indirectly it has access to the global state, such as when trying to open a file in FileType.

The action has access to the namespace, though usually that is for the purpose of setting a value (attribute). It can check the values of other attributes, but that ends up limiting the order in which attributes are set (e.g. --force has to come before database).

You can also check namespace attributes after parse_args. You can still used the argparse error mechanism by calling parser.error('your message'). It may be easier to check values at this stage, since you don't have to worry about the order of the strings in sys.argv.



来源:https://stackoverflow.com/questions/18657151/argparse-accessing-multiple-arguments-at-once

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!