繁体   English   中英

argparse:位置参数之间的可选参数

[英]argparse: optional argument between positional arguments

我想模拟大多数命令行实用程序的行为,其中可选参数可以放在命令行中的任何位置,包括位置参数之间,例如在这个mkdir示例中:

mkdir before --mode 077 after

在这种情况下,我们知道--mode正好接受 1 个参数,因此beforeafter都被视为位置参数。 可选部分--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 before --mode 077 after结果:

mkdir.py: error: unrecognized arguments: after

如何让argparse接受位置参数之间的可选参数(具有固定的已知项目数)?

Python 3.7开始, argparse现在似乎支持这种 Unix 风格的解析:

混合解析

ArgumentParser.parse_intermixed_args(args=None, namespace=None)

许多 Unix 命令允许用户将可选参数与位置参数混合使用。 parse_intermixed_args()parse_known_intermixed_args()方法支持这种解析风格。

有一个警告,但对于“简单”选项,它不会影响它们:

这些解析器不支持所有 argparse 功能,如果使用了不受支持的功能,则会引发异常。 特别是,不支持子解析器、 argparse.REMAINDER和同时包含可选项和位置的互斥组。

(我花了 1 个小时试图理解为什么 Python argparse文档中的示例似乎没有包含它后,发布了这个 FAQ 风格的问题,只是偶然发现了一个有点不相关的问题,其中包含对这个“混合”函数的提及在评论中,我无法再次找到以正确引用它。)

我不熟悉 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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM