2010-10-01 13 views
6

Cuando uso optparse quiero obtener toda la cadena después de una opción, pero solo obtengo parte de ella hasta el primer espacio.Python optparse y espacios en un argumento

ej .:

python myprog.py --executable python someOtherProg.py 

Lo que obtengo en 'ejecutable' es sólo 'pitón'.

¿Es posible analizar estas líneas usando optparse o tiene que usar argparse para hacerlo?

€:. Ya he probado encerrándolo en "s Pero después de cavar más lejos en el código que se enteraron de que la invocación subproceso no puede manejar el argumento

La cadena con la línea de comandos se embutida en una. lista args ''.

args = [self.getExecutable()] + self.getArgs().split() 

Es como

"[python D:\\\workspace\\\myprog\\\src\\\myprog.py]" 

que me da el sistema no puede encontrar el archivo de excepción. Cuando uso

args[0] 

funciona. Pero pierdo los argumentos para el ejecutable.

El módulo de subproceso crea un cmdline de una lista si no obtiene una cadena en primer lugar, por lo que no puedo explicar ese comportamiento en este momento.

Respuesta

12

Puede encerrarlos entre comillas para que funcionen con el código existente.

python myprog.py --executable "python someOtherProg.py" 

¿Es posible analizar dichas líneas usando optparse o tiene que utilizar argparse para hacerlo?

No sé si/cómo puede hacerlo con optparse que realmente no he trabajado con optparse.

Sin embargo, puedo ayudarlo con argparse. Aquí está un ejemplo rápido:

#!/usr/bin/python 
import argparse, sys 

if __name__ == '__main__': 
    parser = argparse.ArgumentParser(description = 'Demonstration of Argparse.') 
    parser.add_argument('-e', '--executable', nargs = '+', help = 'List of executables') 
    args = parser.parse_args(sys.argv[1:]) 
    print args.executable 

y uso:

[email protected]:~$ python myprog.py --executable python someOtherProg.py 
['python', 'someOtherProg.py'] 

También me gustaría recomendar la conmutación optparse-argparse. Optparse es deprecated desde 2.7.

4

El comportamiento que ve proviene del hecho de que es su shell, no python, el que analiza la línea de comandos y la separa en las palabras de sys.argv. Python es lanzado por el shell a través de exec() con argv ya poblado.

La mayoría de las conchas dividirán los objetos argv en espacios a menos que les indique que no citen ni escapen.

Las cotizaciones funcionan como se describió anteriormente.

En muchas conchas que podría hacer esto:

python myprog.py --executable python\ someOtherProg.py 

La barra invertida se escapa el siguiente espacio sin necesidad de cotizaciones.

+0

Prepárese para sorprenderse: en virtud de Python 3.5, un espacio escapado se representan literalmente por sys.argv! En C, tenemos 'pitón tonto algunos':' argv [1] '=' "python" ',' argv [2] '=' "some" '. pitón "tonto" algunos "': 'argv [1]' = '" python algunos "'. Y 'tonto python \ some':' argv [1] '=' "python algunos" '. Pero con Python 3.5 tenemos 'silly.py python some':' argv [1] '=' "python" ',' argv [2] '=' "some" '. 'tonto.py" pitón algunos "': 'argv [1]' = '" pitón algunos "'. Y 'silly.py python \ some':' argv [1] '=' "python \\" ',' "some" '. ¡Asombroso! – Urhixidur

4

Si sabe cuántas palabras después de la bandera argumento que se va a conseguir, se puede modificar la forma de crear la opción --executable en en optparse para manejar adecuadamente la situación:

En lugar de tomar un sola palabra después de la bandera opción se puede establecer el analizador optparse para buscar dos (o más) palabras:

from optparse import OptionParser 
parser = OptionParser() 

parser.add_option("-f", "--file", action="store", dest="filename", 
         help="File to be processed.", metavar="FILE") 
parser.add_option("-e", "--executable", action="store", dest="my_exe", 
         help="Command to be executed", metavar="EXE", 
         nargs=2) 

En este fragmento, el -f o --file opción solo espera una sola palabra y la almacena como una cadena (el valor predeterminado) en la variable filename. Por el contrario, la opción -e, --executable espera dos palabras debido a la opción nargs=2. Esto dará como resultado que las dos palabras encontradas detrás de la bandera -e o --executable se almacenen como cadenas en una lista de Python my_exe.

Consulte: http://docs.python.org/library/optparse.html para obtener más información sobre optparse, y recuerde que ha quedado obsoleto a partir de 2.7 a favor de argparse.

1

Solo para finalizar esta lista de respuestas si no puede actualizar a argparse.

Optparse no puede manejar estas situaciones (varias cadenas). Solo puede usar nargs para especificar una cantidad particular de valores valiosos, pero no hay nada como "uno o más". Usted necesita hackear o utilizar una biblioteca diferente (por ejemplo, argparse u otro).

+0

¿me puede decir cómo se puede manejar usando argparse? sin usar 'sys.argv' Supongo que argparse tampoco tiene características como' parse_string' en lugar 'parse_args', p. ej. para analizar cadenas que tienen espacios como '" uno o más "' – shahjapan

+0

argparse también está limitado, no tengo mucha experiencia con él :-( – lzap

+0

veo otra solución proporcionada por mí, debería funcionar con 'argparse' y' optparse 'como su independencia mediante el uso de' shlex' lib. – shahjapan

6

He encontrado otra buena alternativa shlex - Una clase de analizador léxico para sintaxis simples tipo concha. enlace

Fuente: How to parse a command line with regular expressions?

>>> import shlex 
>>> shlex.split('"param 1" param2 "param 3"') 
['param 1', 'param2', 'param 3'] 
>>> shlex.split('"param 1" param2 "param 3"') 
Traceback (most recent call last): 
    [...] 
ValueError: No closing quotation 
>>> shlex.split('"param 1" param2 "param 3\\""') 
['param 1', 'param2', 'param 3"'] 
Cuestiones relacionadas