script - parametros por linea de comandos python
especificando una lista como un argumento de lĂnea de comando en python (6)
Estoy usando getopt para procesar un argumento opcional de la línea de comandos, que debería aceptar una lista. Algo como esto:
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 convertirla en una cadena? (usando getopt)
B) Si debo convertir la lista en una cadena, ¿cómo convertir esta lista en una cadena? por ejemplo, algo como mylist.split ("?") para deshacerse de los corchetes? ¿hay una mejor manera?
Gracias
Desde la página de ayuda de python optparse: "
parser.add_option("-f")
parser.add_option("-p", type="float", nargs=3, dest="point")
Como analiza la linea de comando
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparse establecerá
options.f = "foo.txt"
options.point = (1.0, -3.5, 4.0)
options.f = "bar.txt"
"
Hay dos opciones que puedo pensar:
- Use optparse y use la acción de
append
para especificar lo que desea hacer como:foo.py --my_list=1 --my_list=2 ...
- Especifique su línea de comando como
foo.py --my_list=''1,2,3,4,5''
, y luego usex.split('','')
para obtener sus valores en una lista. Puedes usargetopt
ooptparse
para este método.
La ventaja del primer método es que puede obtener valores enteros en la lista directamente, a expensas de que la línea de comandos sea más larga (pero puede agregar una opción de carácter --my_list
para --my_list
si lo desea). La ventaja de la segunda es la línea de comando más corta, pero después de la split()
, debe convertir los valores de cadena ''1''
, ''2''
, etc., a números enteros (también es bastante fácil).
He sido redirigido desde la pregunta dup:
Cómo pasar una matriz a Python a través de la línea de comandos
Estoy respondiendo esa pregunta:
Los argumentos en la línea de comando son cadenas, no se analizan como literales en el programa.
argv construye las cadenas automáticamente en una lista a partir de los argumentos de la línea de comandos (separados por espacios), en resumen, sys.argv
es una lista.
from sys import argv
cmd = "arr = {sys.argv[1]}".format(argv)
exec(cmd)
print(arr[2])
Si no puedo usar un analizador estándar (optparse o argparse) para mi aplicación, entonces uso la función ast.literal_eval para analizar los argumentos de entrada de la lista de tipos de la siguiente manera:
import sys, ast
inputList = ast.literal_eval( sys.argv[1] )
print type( inputList )
print inputList
Supongamos que este código se almacena en el archivo testParser.py. Al ejecutar el script:
$ python testParser.py "[1,2,3,4, [123, 456, 789], ''asdasd'']"
Obtenemos la siguiente salida:
<type ''list''>
[1, 2, 3, 4, [123, 456, 789], ''asdasd'']
Por lo tanto, utilizando la función ast.literal_eval suficientemente segura e insertando la lista como una cadena de código tenemos el resultado deseado.
Enlaces útiles:
¿Usando eval () de python vs. ast.literal_eval ()?
http://docs.python.org/2/library/functions.html?highlight=eval#eval
Tal vez debería simplemente incluir el argumento entre comillas?
foo.py "--my_list=[1, 2, 3, 4,5]"
De lo contrario, cada espacio será tratado como un separador de argumentos.
Una forma actualizada es usar la biblioteca argparse
y agregar la lista como un argumento de línea de comando. De esta manera, no tiene 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
)
Lo que entonces llamarías así:
python3 someprogram.py -values 1 2 3