argparse:位置参数之间的可选参数
argparse: optional argument between positional arguments
我想模拟大多数命令行实用程序的行为,其中可选参数可以放在命令行的任何位置,包括 between 位置参数,例如在这个 mkdir
示例:
mkdir before --mode 077 after
在这种情况下,我们知道 --mode
正好接受 1 个参数,因此 before
和 after
都被视为位置参数。可选部分 --mode 077
实际上可以放在命令行中的任何地方 。
但是,对于 argparse
,以下代码不适用于此示例:
# mkdir.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--mode', nargs=1)
parser.add_argument('dirs', nargs='*')
args = parser.parse_args()
运行 ./mkdir.py before --mode 077 after
结果:
mkdir.py: error: unrecognized arguments: after
如何让 argparse
接受位置参数之间的可选参数(具有固定的已知数量的项目)?
从Python 3.7开始,好像argparse
现在支持这种Unix-style解析:
Intermixed parsing
ArgumentParser.parse_intermixed_args(args=None, namespace=None)
A number of Unix commands allow the user to intermix optional arguments with positional arguments. The parse_intermixed_args()
and parse_known_intermixed_args()
methods support this parsing style.
有一个警告,但对于“简单”选项,它不会影响它们:
These parsers do not support all the argparse features, and will raise exceptions if unsupported features are used. In particular, subparsers, argparse.REMAINDER
, and mutually exclusive groups that include both optionals and positionals are not supported.
(我在花了 1 小时试图理解为什么 Pythonargparse
文档中的示例似乎没有包含它之后发布了这个 FAQ-style 问题,只是偶然发现了一个有点不相关的问题,其中在评论中提到了这个“混合”函数,我无法再次找到它来正确引用它。)
我不熟悉 argparse,所以我会编写自己的代码来处理参数。
import sys
#the first argument is the name of the program, so we skip that
args = sys.argv[1:]
#just for debugging purposes:
argsLen = len(args)
print(args, argsLen)
#Create a list that will contain all of the indeces that you will have parsed through
completedIndeces = []
i = 0
#add the index to the completed indeces list.
def goToNextIndex(j):
global i
completedIndeces.append(j)
i += 1
def main():
global i
###core logic example
#Go through each item in args and decide what to do based on the arugments passed in
for argu in args:
if i in completedIndeces:
print("breaking out")
#increment i and break out of the current loop
i += 1
# If the indeces list has the index value then nothing else is done.
pass
elif argu == "joe":
print("did work with joe")
goToNextIndex(i)
elif argu == "sam":
print("did work with sam")
goToNextIndex(i)
elif argu == "school":
print("going to school")
goToNextIndex(i)
# If the argument has other arguments after it that are associated with it
# then add those indeces also to the completed indeces list.
#take in the argument following school
nextArg = i
#Do some work with the next argument
schoolName = args[nextArg]
print(f"You're going to the school called {schoolName}")
#make sure to skip the next argument as it has already been handled
completedIndeces.append(nextArg)
else:
print(f"Error the following argument is invalid: {argu}")
goToNextIndex(i)
print(f"Value of i: {i}")
print(f"completed indeces List: {completedIndeces}")
main()
我想模拟大多数命令行实用程序的行为,其中可选参数可以放在命令行的任何位置,包括 between 位置参数,例如在这个 mkdir
示例:
mkdir before --mode 077 after
在这种情况下,我们知道 --mode
正好接受 1 个参数,因此 before
和 after
都被视为位置参数。可选部分 --mode 077
实际上可以放在命令行中的任何地方 。
但是,对于 argparse
,以下代码不适用于此示例:
# mkdir.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--mode', nargs=1)
parser.add_argument('dirs', nargs='*')
args = parser.parse_args()
运行 ./mkdir.py before --mode 077 after
结果:
mkdir.py: error: unrecognized arguments: after
如何让 argparse
接受位置参数之间的可选参数(具有固定的已知数量的项目)?
从Python 3.7开始,好像argparse
现在支持这种Unix-style解析:
Intermixed parsing
ArgumentParser.parse_intermixed_args(args=None, namespace=None)
A number of Unix commands allow the user to intermix optional arguments with positional arguments. The
parse_intermixed_args()
andparse_known_intermixed_args()
methods support this parsing style.
有一个警告,但对于“简单”选项,它不会影响它们:
These parsers do not support all the argparse features, and will raise exceptions if unsupported features are used. In particular, subparsers,
argparse.REMAINDER
, and mutually exclusive groups that include both optionals and positionals are not supported.
(我在花了 1 小时试图理解为什么 Pythonargparse
文档中的示例似乎没有包含它之后发布了这个 FAQ-style 问题,只是偶然发现了一个有点不相关的问题,其中在评论中提到了这个“混合”函数,我无法再次找到它来正确引用它。)
我不熟悉 argparse,所以我会编写自己的代码来处理参数。
import sys
#the first argument is the name of the program, so we skip that
args = sys.argv[1:]
#just for debugging purposes:
argsLen = len(args)
print(args, argsLen)
#Create a list that will contain all of the indeces that you will have parsed through
completedIndeces = []
i = 0
#add the index to the completed indeces list.
def goToNextIndex(j):
global i
completedIndeces.append(j)
i += 1
def main():
global i
###core logic example
#Go through each item in args and decide what to do based on the arugments passed in
for argu in args:
if i in completedIndeces:
print("breaking out")
#increment i and break out of the current loop
i += 1
# If the indeces list has the index value then nothing else is done.
pass
elif argu == "joe":
print("did work with joe")
goToNextIndex(i)
elif argu == "sam":
print("did work with sam")
goToNextIndex(i)
elif argu == "school":
print("going to school")
goToNextIndex(i)
# If the argument has other arguments after it that are associated with it
# then add those indeces also to the completed indeces list.
#take in the argument following school
nextArg = i
#Do some work with the next argument
schoolName = args[nextArg]
print(f"You're going to the school called {schoolName}")
#make sure to skip the next argument as it has already been handled
completedIndeces.append(nextArg)
else:
print(f"Error the following argument is invalid: {argu}")
goToNextIndex(i)
print(f"Value of i: {i}")
print(f"completed indeces List: {completedIndeces}")
main()