[英]Can I direct Python's argparse to treat all arguments after a positional arg as also positional, even if they match an optional arg?
I am writing a utility (call it runner
) which, as its main functionality, runs another script.我正在编写一个实用程序(称为runner
),它的主要功能是运行另一个脚本。 That script to be run is passed as an argument, as well as any arguments that should be passed to the script.要运行的脚本以及应传递给脚本的任何 arguments 作为参数传递。 So, for example:因此,例如:
runner script.py arg1 arg2
will run script.py
as a subprocess, with arg1
and arg2
as arguments.将script.py
作为子进程运行, arg1
和arg2
为 arguments。 This is easy enough, using the following:这很容易,使用以下内容:
parser = argparse.ArgumentParser()
parser.add_argument("script", help="The script to run")
parser.add_argument("script_args", nargs="*", help="Script arguments", default=[])
args = parser.parse_args()
The complication is that I have some additional arguments passed to runner
, which modify how the script will be called.复杂之处在于我有一些额外的 arguments 传递给runner
,它修改了脚本的调用方式。 One of these is --times
, which will be used to determine how many times to run the script.其中之一是--times
,它将用于确定运行脚本的次数。 So:所以:
runner --times 3 script.py arg1 arg2
will run script.py
three times, with arg1
and arg2
as arguments.将运行script.py
三次, arg1
和arg2
为 arguments。
The problem I am trying to solve is this.我要解决的问题是这个。 I want any arguments after the script name to be treated as arguments to pass to the script, even if they match argument names of runner
.我希望脚本名称之后的任何 arguments 都被视为 arguments 传递给脚本,即使它们与runner
的参数名称匹配。 So:所以:
runner script.py arg1 arg2 --times 3
should run script.py once , and pass the arguments arg1
, arg2
, --times
, and 3
to script.py.应该运行 script.py一次,并将--times
arg1
、 arg2
、--times 和3
传递给 script.py。
I can't find any way to tell the ArgumentParser to treat all arguments after the script
arg as positional.我找不到任何方法告诉 ArgumentParser 将script
arg 之后的所有 arguments 视为位置。
I know the caller of the script could force this behavior using the --
special argument , so the following would yield the desired behavior:我知道脚本的调用者可以使用--
特殊参数强制执行此行为,因此以下将产生所需的行为:
runner -- script.py arg1 arg2 --times 3
but I want the program to take care of this instead.但我希望程序来处理这个问题。 Is this behavior possible?这种行为可能吗?
First of all, you should not do this.首先,你不应该这样做。 It is more clear, if you make it explicit which arguments apply to which program (call), maybe you can sourround the whole script parameters of the called script in quotations like:更清楚的是,如果您明确指出哪个 arguments 适用于哪个程序(调用),也许您可以将被调用脚本的整个脚本参数用引号括起来,例如:
runner script.py "arg1 arg2 --times 3"
But if you want to do this your way, you can overwrite the ArgumentParser.parse_arguments
function with your own.但是,如果您想以自己的方式执行此操作,则可以用自己的方式覆盖ArgumentParser.parse_arguments
function。 I only build an example to illustrate how it is possible (for me it's working), but i do not know if there are any sideeffects:我只是建立一个例子来说明它是如何可能的(对我来说它正在工作),但我不知道是否有任何副作用:
import argparse
from typing import Optional, Sequence
class ErrorCatchingArgumentParser(argparse.ArgumentParser):
def parse_args(self, args: Optional[Sequence[str]] = ...) -> argparse.Namespace:
ns, a = super().parse_known_args(args=args)
args.insert(args.index(ns.script), "--")
return super().parse_args(args=args)
if __name__ == '__main__':
arguments = ["--time", "3", "myscript", "my_args", "myargs2", "--time", "5"]
parser = ErrorCatchingArgumentParser()
parser.add_argument("script", help="The script to run")
parser.add_argument("--time", help="The script to run")
parser.add_argument("script_args", nargs="*", help="Script arguments", default=[])
print(arguments)
namespace = parser.parse_args(arguments)
print(arguments)
print(namespace)
Output: Output:
['--time', '3', 'myscript', 'my_args', 'myargs2', '--time', '5']
['--time', '3', '--', 'myscript', 'my_args', 'myargs2', '--time', '5']
Namespace(script='myscript', time='3', script_args=['my_args', 'myargs2', '--time', '5'])
It它
parse_known_args
of superclass to get all arguments set (and do not raise an error)使用超类的parse_known_args
解析给定的 args 以获取所有 arguments 集(并且不引发错误)script
variable and insert the --
before it in the argument list搜索您的script
变量并在参数列表中插入--
之前parse_args
function of superclass to get "the real" arguments使用超类的parse_args
function 解析 arguments 以获得“真正的” argumentsIn the output you can see the original arguments, the manipulated arguments and the created namespace.在 output 中,您可以看到原始的 arguments、操纵的 arguments 和创建的命名空间。
But i think you should NOT do this, anyway.但我认为你不应该这样做,无论如何。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.