Is it possible to use argparse to capture an arbitrary set of optional arguments?

情到浓时终转凉″ 提交于 2020-01-25 06:54:12

问题


Is it possible to use argparse to capture an arbitrary set of optional arguments?

For example both the following should be accepted as inputs:

python script.py required_arg1 --var1 value1 --var2 value2 --var3 value3

python script.py required_arg1 --varA valueA --var2 value2 --varB valueB

a priori I don't know what optional arguments would be specified receive but would handle them accordingly.


回答1:


This is kind of a hackish way, but it works very well:

Check, which arguments are not added and add them

parser=argparse.ArgumentParser()
parser.add_argument("foo")
parser.add_argument("-bar", type=int)
#parser can have any arguments, whatever you want!

parsed, unknown = parser.parse_known_args() #this is an 'internal' method
# which returns 'parsed', the same as what parse_args() would return
# and 'unknown', the remainder of that
# the difference to parse_args() is that it does not exit when it finds redundant arguments

for arg in unknown:
    if arg.startswith(("-", "--")):
        #you can pass any arguments to add_argument
        parser.add_argument(arg, type=<your type>, ...)

args=parser.parse_args()

For example:

python arbitrary_parser.py ha -bar 12 -lol huhu -rofl haha

Then the result would be

args = Namespace(bar=12, foo='ha', lol='huhu', rofl='haha')



回答2:


Possible? possibly, but I wouldn't recommend it. argparse is the not best tool for parsing this kind of input, or conversely, this a poor argument specification from an argparse perspective.

Have you thought about what the usage line should look like? How would explain this to your users?

How would you parse this working from sys.argv directly? It looks like you could collect 3 pieces:

 prog = sys.argv[0]
 arg1 = sys.argv[1]
 keys = sys.argv[2::2]
 # maybe strip -- off each
 values = sys.argv[3::2]
 kvdict = {k:v for k, v in zip(keys, values)}

There are other SO questions asking about generic key:value pairs. Things like:

 --args key1:value1 key2:value2

This can be handled with nargs='*' and an action that splits each input string on : (or =) and stores things by key.

Your requirement is least amenable to argparse use because it requires bypassing the whole idea of matching argument flags with strings in argv. It requires, some how, turning off all the normal argparse parsing.

Looks like I suggested the same thing a couple of years ago

Parse non-pre-defined argument

or earlier

Using argparse to parse arguments of form "arg= val"



来源:https://stackoverflow.com/questions/58742214/passing-arbitrary-arguments-how-should-i-go-about-the-code

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