猿问

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

我想模拟大多数命令行实用程序的行为,其中可选参数可以放置在命令行中的任何位置,包括位置参数之间,如下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接受位置参数之间的可选参数(具有固定的、已知数量的项目)?


慕尼黑的夜晚无繁华
浏览 192回答 2
2回答

慕田峪7331174

从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 个小时试图理解为什么 Pythonargparse文档中的示例似乎没有包含它,然后偶然发现了一个有点不相关的问题,其中包含对这个“混合”函数的提及一条评论,我无法再次找到正确引用它的评论。)

繁星淼淼

我不熟悉 argparse 所以我会编写自己的代码来处理参数。import sys#the first argument is the name of the program, so we skip thatargs = 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 throughcompletedIndeces = []i = 0#add the index to the completed indeces list.def goToNextIndex(j):    global i    completedIndeces.append(j)    i += 1def 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()
随时随地看视频慕课网APP

相关分类

Python
我要回答