问题
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