2010-01-18 12 views
17

Estoy usando getopt para procesar un argumento opcional de línea de comandos, que debería aceptar una lista. Algo como esto:especificando una lista como un argumento de línea de comando en python

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

Pero esto recorta todo después de "[1,"

Mis preguntas son: A) ¿Hay una manera de especificar una lista sin necesidad de convertirlo en una cadena? (usando getopt)

B) Si voy a convertir la lista en una cadena, ¿cómo convertir esta lista en una cadena? p.ej. algo así como mylist.split ("?") para deshacerse de los corchetes ?? hay una mejor manera?

Gracias

Respuesta

23

Hay dos opciones que se me ocurren:

  • Uso optparse, y el uso append acción para especificar lo que quiere hacer como: foo.py --my_list=1 --my_list=2 ....
  • Especifique su línea de comandos como foo.py --my_list='1,2,3,4,5', y luego use x.split(',') para obtener sus valores en una lista. Puede usar getopt o optparse para este método.

La ventaja del primer método es que se pueden obtener valores enteros en la lista directamente, a expensas de la línea de comandos es más largo (pero puede agregar una opción de un solo charecter para --my_list si lo desea). La ventaja de la segunda es la línea de comando más corta, pero después de split(), necesita convertir los valores de cadena '1', '2', etc., en números enteros (bastante fácil también).

+2

ya que esta publicación tiene 5 años, 'optparse' ahora está en desuso para' argparse' – SAAD

+0

¿Qué quiere decir con 'use append action'? Parece emocionante, pero no estoy seguro de lo que estás hablando. –

+0

@MonicaHeddneck Consulte https://docs.python.org/3/library/optparse.html#standard-option-actions - tienen un ejemplo de la acción "append": 'parser.add_option (" - t "," --tracks ", action =" append ", type =" int ")'. –

7

¿Tal vez debería simplemente incluir el argumento entre comillas?

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

De lo contrario, cada espacio se tratará como un separador de argumentos.

+2

Y eso no es debido a la pitón pero debido a la cáscara que analiza los argumentos y les proporciona al programa de pitón. – extraneon

+1

Parcialmente cierto. En Windows, la línea de comando es solo una cadena. E incluso UNIX no tiene ninguna estructura de datos especial que pase argumentos al programa, todavía es solo una cadena. Sin embargo, es una convención ampliamente implementada, pero no universal. Y sí, el tiempo de ejecución de C tiene especificaciones para eso. – Joey

+1

También puede hacer '--my-list =" [1, 2, 3, 4,5] "'. Usualmente uso este formulario porque generalmente es algo como '--my-list =" $ MY_LIST "'. –

1

Desde la página pitón optparse ayuda: "

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

Como se analiza la línea de comandos

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

optparse fijará

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

"

10

Si no puedo utilizar un programa de análisis estándar (optparse o argparse) a mi solicitud luego utilizar la función ast.literal_eval para analizar los argumentos de entrada de lista de tipos de la siguiente manera:

import sys, ast 

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

dejar suponer que este código se almacena en el archivo testParser.pyMediante la ejecución de la secuencia de comandos:

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

obtenemos el siguiente resultado:

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

Por lo tanto, el uso de la función lo suficientemente seguro ast.literal_eval y la inserción de la lista como una cadena de código tenemos el resultado deseable.

Enlaces de interés:

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

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

1

Una forma actualizada es el uso de la biblioteca argparse y añadir la lista como argumento de línea de comandos. De esta manera, no tienes que hacer ningún análisis manual.

Ejemplo:

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 
    ) 

Qué usted entonces llamar así:

python3 someprogram.py -values 1 2 3 
Cuestiones relacionadas