Esto puede no ser útil para usted, pero este problema parece ser más fácil si puede dividir sys.argv
en partes - Esencialmente, debe ser capaz de averiguar qué piezas se supone que son argumentos "posicionales" (no es realmente posicional ya que, como dices, pueden ocurrir en cualquier lugar) y qué piezas se supone que son algún tipo de argumento. En el siguiente ejemplo, lo configuré para que funcione con su ejemplo, pero podría fácilmente dividir sys.argv
en archivos, o en cierto tipo de archivo. La función condition
depende de usted para escribir. El resto (con suerte) será autoexplicativo.
import argparse
import sys
import copy
import os
def split_list(lst,condition):
current=[]
out=[current]
for arg in lst:
current.append(arg)
if(condition(arg)):
current=[]
out.append(current)
return out
parser=argparse.ArgumentParser()
parser.add_argument('-m',action='store')
parser.add_argument('-r',default='0',action='store')
#pieces=split_list(sys.argv[1:],os.path.isfile)
pieces=split_list(sys.argv[1:],lambda x: x in ('foo','bar','baz','quux'))
options={} #use collections.OrderedDict if order matters -- or some more suitable data structure.
default=argparse.Namespace()
for args in pieces:
if(not args):
continue
ns=copy.deepcopy(default)
default=parser.parse_args(args[:-1],namespace=ns)
options[args[-1]]=default
print (options)
¿El conjunto de "estados de argumento" es constante? p.ej. ¿sabes de antemano si solo '('foo', 'bar', 'baz', 'quux' ...) alguna vez se utilizarán? ¿O el usuario puede poner lo que quiera siempre que lo desee? – mgilson
@mgnilson - Cualquier cosa donde quieran; lo que estoy viendo es una lista de nombres de archivos y opciones de procesamiento. Basado en el manejo de argumentos posicionales de 'argparse', estoy pensando que esto no se puede hacer sin una acción personalizada que rompa el modelo, que es con lo que estoy jugando actualmente. –
Estaba pensando en acciones personalizadas también, pero eso es complicado porque argparse parece suponer que todos los argumentos posicionales se dan juntos. El único remedio es usar 'nargs = '*'' en todas partes y luego dentro de todas tus acciones verificar para asegurarte de que tienes el número correcto. (que parece frágil en el mejor de los casos). Por supuesto, esto se vuelve mucho más fácil si se permite: '-m 1 -f foo -r 2 -f bar -r 7 -f baz -m 6 -f quux' – mgilson