2010-10-01 1 views
6

Quando si utilizza optparse voglio ottenere l'intera stringa dopo un'opzione, ma ottengo solo una parte di esso fino al primo spazio.Python optparse e spazi in un argomento

es .:

python myprog.py --executable python someOtherProg.py 

cosa ottengo in 'eseguibile' è solo 'python'.

È possibile analizzare tali righe utilizzando optparse o si deve utilizzare argparse per farlo?

€:. Ho già provato racchiudendolo in "s Ma dopo aver scavato ulteriormente nel codice che ho scoperto che l'invocazione sottoprocesso non può gestire l'argomento

La stringa con la riga di comando ottiene stipati in una. lista ''. args

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

E 'come

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

Questo mi dà il sistema non riesce a trovare un'eccezione file. Quando uso

args[0] 

funziona. Ma perdo gli argomenti dell'eseguibile.

Il modulo di sottoprocesso crea una cmdline da un elenco se non ottiene una stringa in primo luogo, quindi non posso spiegare questo comportamento al momento.

risposta

12

È possibile racchiuderle tra virgolette per farle funzionare con il codice esistente.

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

E 'possibile analizzare tali linee utilizzando optparse o devi usare argparse per farlo?

Non so se/come si può fare con optparse come non ho davvero lavorato con optparse.

Posso comunque aiutarti con argparse. Ecco un rapido esempio:

#!/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 

e di utilizzo:

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

Consiglio anche il passaggio optparse-argparse. Optparse è deprecated dal 2.7.

4

Il comportamento che si vede deriva dal fatto che è la shell, non python, che analizza la riga di comando e la separa nelle parole di sys.argv. Python viene lanciato dalla shell tramite exec() con argv già popolato.

La maggior parte delle shell dividerà gli oggetti argv agli spazi a meno che non dite loro di non citandoli o scappando.

Le virgolette funzionano come descritto sopra.

In molte conchiglie si potrebbe fare questo:

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

Il backslash sfugge al seguente spazio senza richiedere preventivi.

+0

Preparati a essere stupito: sotto Python 3.5, uno spazio di escape viene escape da sys.argv! In C, abbiamo 'silly python some':' argv [1] '=' "python" ',' argv [2] '=' "some" '. 'silly" python some "': 'argv [1]' = '" python alcuni "'. E 'silly python \ some':' argv [1] '=' "python alcuni" '. Ma con Python 3.5 abbiamo 'silly.py python some':' argv [1] '=' "python" ',' argv [2] '=' "some" '. 'silly.py" python some "': 'argv [1]' = '" python alcuni "'. E 'silly.py python \ some':' argv [1] '=' "python \\" ',' "alcuni" '. Stupefacente! – Urhixidur

4

Se si sa quante parole dopo la bandiera argomento che si sta per ottenere, è possibile modificare il modo in cui si crea l'opzione --executable in in optparse per gestire correttamente la situazione:

Invece di prendere un singolo parola dopo il flag di opzione è possibile impostare il optparse parser per cercare due (o più) parole:

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) 

In questo frammento, il -f o --file l'opzione si aspetta solo una singola parola e la memorizza come una stringa (il valore predefinito) nella variabile filename.

Al contrario l'opzione -e, --executable prevede due parole a causa dell'opzione nargs=2. Ciò si tradurrà in due parole trovate dietro il flag -e o --executable da memorizzare come stringhe in un elenco Python my_exe.

Check out: http://docs.python.org/library/optparse.html per ulteriori informazioni su optparse e ricorda che è stato dichiarato obsoleto a partire dal 2.7 a favore di argparse.

1

Solo per finalizzare questo elenco di risposte se non è possibile eseguire l'aggiornamento a argparse.

Optparse non è in grado di gestire queste situazioni (stringhe multiple). Puoi usare solo nargs per specificare una quantità particolare di valori, ma non c'è nulla come "uno o più". È necessario per modificare l' o utilizzare la libreria diversa (ad esempio argparse o altro).

+0

puoi dirmi come può essere gestito usando argparse? w/o usando 'sys.argv' Suppongo che argparse non abbia caratteristiche come' parse_string' invece 'parse_args', ad es. per analizzare stringhe aventi spazi come '" uno o più "' – shahjapan

+0

argparse è troppo limitato, non ho molta esperienza con questo :-( – lzap

+0

vedi un'altra soluzione da me fornita, dovrebbe funzionare con 'argparse' così come' optparse 'come indipendente usando' shlex' lib. – shahjapan

6

Ho trovato un'altra buona alternativa shlex - Una classe di analizzatore lessicale per semplici sintassi di tipo shell. Link

Fonte: 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"']