2010-01-18 8 views
17

Sto usando getopt per elaborare un argomento facoltativo della riga di comando, che dovrebbe accettare un elenco. Qualcosa di simile a questo:che specifica un elenco come argomento della riga di comando in python

foo.py --my_list=[1, 2, 3, 4,5] 

Ma questo rifila tutto dopo "[1,"

Le mie domande sono: A) C'è un modo per specificare un elenco senza convertirlo in una stringa? (usando getopt)

B) Se devo convertire l'elenco in una stringa, come convertire questo elenco in una stringa? per esempio. qualcosa come mylist.split ("?") per sbarazzarsi di parentesi quadre ?? C'è un modo migliore?

Grazie

risposta

23

ci sono due opzioni che mi viene in mente:

  • Usa optparse, e utilizzare append azione per specificare cosa si vuole fare come: foo.py --my_list=1 --my_list=2 ....
  • Specificare la riga di comando come foo.py --my_list='1,2,3,4,5' e quindi utilizzare x.split(',') per ottenere i valori in un elenco. È possibile utilizzare getopt o optparse per questo metodo.

Il vantaggio del primo metodo è che si può ottenere valori interi nella lista direttamente, a spese della riga di comando di essere più lungo (ma è possibile aggiungere un singolo-charecter opzione per --my_list se si desidera). Il vantaggio del secondo è la linea di comando più breve, ma dopo lo split(), è necessario convertire i valori di stringa '1', '2', ecc., In numeri interi (molto semplice).

+2

poichè questo post ha 5 anni, 'optparse' è ora deprecato per' argparse' – SAAD

+0

Cosa intendi con 'usa aggiungi azione'? Sembra eccitante ma non è sicuro di cosa stai parlando. –

+0

@MonicaHeddneck Vedi https://docs.python.org/3/library/optparse.html#standard-option-actions - hanno un esempio dell'azione "append": 'parser.add_option (" - t "," --tracks ", action =" append ", type =" int ")'. –

7

Forse dovresti racchiudere l'argomento tra virgolette?

foo.py "--my_list=[1, 2, 3, 4,5]" 

In caso contrario, ogni spazio verrà considerato come separatore per argomenti.

+2

E questo è non a causa di python, ma a causa del guscio che analizza gli argomenti e li mette a disposizione del programma Python. – extraneon

+1

Parzialmente vero. Su Windows la riga di comando è solo una stringa. Persino UNIX non ha alcuna struttura dati speciale che trasmetta argomenti al programma, è pur sempre una stringa. Tuttavia, è una convenzione ampiamente implementata, ma non universale. E sì, il runtime C ha le specifiche per questo. – Joey

+1

Puoi anche fare '--my-list =" [1, 2, 3, 4,5] "'. Di solito uso questo modulo perché di solito è qualcosa come '--my-list =" $ MY_LIST "'. –

1

Dalla pagina pitone optparse aiuto: "

parser.add_option("-f") 
parser.add_option("-p", type="float", nargs=3, dest="point") 

Come si analizza la riga di comando

-f foo.txt -p 1 -3.5 4 -fbar.txt 

optparse imposterà

options.f = "foo.txt" 
options.point = (1.0, -3.5, 4.0) 
options.f = "bar.txt" 

"

10

Se non posso usare un parser standard (optparse o argparse) alla mia domanda allora io uso la funzione ast.literal_eval per analizzare argomenti di input di tipo lista come segue:

import sys, ast 

inputList = ast.literal_eval(sys.argv[1]) 
print type(inputList) 
print inputList 

lasciare supporre che questo codice viene memorizzato nel file testParser.py.Eseguendo lo script:

$ python testParser.py "[1,2,3,4, [123, 456, 789], 'asdasd']" 

otteniamo il seguente risultato:

<type 'list'> 
[1, 2, 3, 4, [123, 456, 789], 'asdasd'] 

Quindi, utilizzando la funzione abbastanza ast.literal_eval sicuro e inserire l'elenco come una stringa di codice abbiamo il risultato desiderabile.

Link utili:

Using python's eval() vs. ast.literal_eval()?

http://docs.python.org/2/library/functions.html?highlight=eval#eval

1

Un modo aggiornato è quello di utilizzare la libreria argparse e aggiungere l'elenco come argomento della riga di comando. In questo modo, non è necessario eseguire alcuna analisi manuale.

Esempio:

parser = argparse.ArgumentParser() 
parser.add_argument(
     "-values", 
     nargs="*", # expects ≥ 0 arguments 
     type=int, 
     default=[35, 40, 50, 60, 70, 80, 90], # default list if no arg value 
    ) 

Che si quindi chiamare in questo modo:

python3 someprogram.py -values 1 2 3 
Problemi correlati