Python: read command line args with argparse in addition to those coming from an external function

岁酱吖の 提交于 2019-12-08 06:15:38

问题


I have two modules in the same package, module1.py and module2.py.

In module1.py I have a function reading command-line args with argparse:

import argparse

def parse_arguments_module1():
    parser = argparse.ArgumentParser()
    optional = parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    required.add_argument('--argA', help='argA', required=True)
    required.add_argument('--argB', help='argB', required=True)
    optional.add_argument('--argC', help='argC')
    optional.add_argument('--argD', help='argD')
    parser._action_groups.append(optional)
    args = parser.parse_args()
    return args

Now suppose in module2.py I import parse_arguments_module1() from module1.py and use it (this works):

from module1 import parse_arguments_module1

if __name__ == '__main__':
    args = parse_arguments_module1()
    print(args)

Use:

python3 module2.py --argA A --argB B --argC C

Output:

Namespace(argA='A', argB='B', argC='C', argD=None)

The question is: how to read arguments in module2.py (required and/or optional) additional to those of module1.py? (I.e. have args in main contain more arguments, just for module2.py)


回答1:


You'd need to use partial parsing with parser.parse_known_args() to achieve what you want, and / or pass your arguments as a list, explicitly.

Normally, without arguments parser.parse_args() takes all values from sys.argv[1:] (so everything but the first element) as the input to parse. If there are elements in that list that can't be parsed, then an error message is printed and sys.exit(1) is called; your script would exit.

So if you want some arguments on sys.argv to go to one parser, and the remainder to another, you want to use parser.parse_known_args() and pass the remainder to the other parser.

I'd split out creating and configuring the ArgumentParser() instances from parsing; so in module1 do:

def module1_argument_parser():
    parser = argparse.ArgumentParser()
    optional = parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    required.add_argument('--argA', help='argA', required=True)
    required.add_argument('--argB', help='argB', required=True)
    optional.add_argument('--argC', help='argC')
    optional.add_argument('--argD', help='argD')
    parser._action_groups.append(optional)
    return parser

def parse_arguments_module1(args=None):
    parser = module1_argument_parser()
    return parser.parse_args(args)

if __name__ == '__main__':
    args = parse_arguments_module1()
    print(args)

and in module2, use the same structure, but re-use the parser from module1:

from module1 import module1_argument_parser

def module2_argument_parser():
    parser = argparse.ArgumentParser()
    # create argument switches, etc.
    return parser

def parse_arguments_module2(args=None):
    parser = module2_argument_parser()
    return parser.parse_args(args)

if __name__ == '__main__':
    module1_parser = module1_argument_parser()
    module1_args, remainder = module1_parser.parse_known_args()
    module2_args = parse_arguments_module2(remainder)
    print(module1_args)
    print(module2_args)


来源:https://stackoverflow.com/questions/52929014/python-read-command-line-args-with-argparse-in-addition-to-those-coming-from-an

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