¿Cómo leer / procesar argumentos de línea de comando?
-
06-07-2019 - |
Pregunta
Originalmente soy un programador en C. He visto numerosos trucos y hacks. leer muchos argumentos diferentes.
¿Cuáles son algunas de las formas en que los programadores de Python pueden hacer esto?
Relacionados
- ¿Cuál es la mejor manera de captar / analizar argumentos de línea de comandos pasados ??a un script de Python?
- Implementando un “[comando] [acción] [parámetro ] "Interfaces de línea de comandos de estilo?
- ¿Cómo puedo procesar argumentos de línea de comandos en Python?
- ¿Cómo formateo la ayuda del argumento posicional usando Python? optparse?
Solución
La solución canónica en la biblioteca estándar es argparse
( docs ):
Aquí hay un ejemplo:
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("-f", "--file", dest="filename",
help="write report to FILE", metavar="FILE")
parser.add_argument("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")
args = parser.parse_args()
argparse
admite (entre otras cosas):
- Múltiples opciones en cualquier orden.
- Opciones cortas y largas.
- Valores predeterminados.
- Generación de un mensaje de ayuda de uso.
Otros consejos
import sys
print("\n".join(sys.argv))
sys.argv
es una lista que contiene todos los argumentos pasados ??al script en la línea de comando.
Básicamente,
import sys
print(sys.argv[1:])
Simplemente evangelizando para argparse que es mejor para estas razones ... esencialmente:
(copiado del enlace)
-
el módulo argparse puede manejar posicional y argumentos opcionales, mientras que optparse puede manejar solo opcional argumentos
-
argparse no es dogmático sobre cuál es su interfaz de línea de comando debería verse como - opciones como -file o / archivo son compatibles, como son opciones requeridas Optparse se niega a admite estas características, prefiriendo pureza sobre practicidad
-
argparse produce más mensajes informativos de uso, incluidos uso de línea de comando determinado a partir de sus argumentos y mensajes de ayuda para tanto posicional como opcional argumentos El módulo optparse requiere que escribas tu propio uso cadena, y no tiene forma de mostrar ayuda para argumentos posicionales.
-
argparse admite acciones que consumir un número variable de argumentos de línea de comando, mientras que optparse requiere que el número exacto de se conocen argumentos (por ejemplo, 1, 2 o 3) por adelantado
-
argparse admite analizadores que despacho a subcomandos, mientras optparse requiere configuración
allow_interspersed_args
y haciendo el envío del analizador manualmente
Y mi favorito personal:
- argparse permite el tipo y
parámetros de acción para
add_argument ()
ser especificado con simple callables, mientras que optparse requiere piratear atributos de clase comoSTORE_ACTIONS
oCHECK_METHODS
para obtener comprobación adecuada de argumentos
También hay argparse
módulo stdlib (un " ; mejora " en el módulo optparse
de stdlib). Ejemplo de la introducción a argparse :
# script.py
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'integers', metavar='int', type=int, choices=range(10),
nargs='+', help='an integer in the range 0..9')
parser.add_argument(
'--sum', dest='accumulate', action='store_const', const=sum,
default=max, help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
Uso:
$ script.py 1 2 3 4
4
$ script.py --sum 1 2 3 4
10
Una forma de hacerlo es usando sys.argv
. Esto imprimirá el nombre del script como primer argumento y todos los demás parámetros que le pase.
import sys
for arg in sys.argv:
print arg
La biblioteca docopt es realmente elegante. Construye un argumento dict a partir de la cadena de uso para su aplicación.
Por ejemplo, del archivo Léame de docopt:
"""Naval Fate.
Usage:
naval_fate.py ship new <name>...
naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
naval_fate.py ship shoot <x> <y>
naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
naval_fate.py (-h | --help)
naval_fate.py --version
Options:
-h --help Show this screen.
--version Show version.
--speed=<kn> Speed in knots [default: 10].
--moored Moored (anchored) mine.
--drifting Drifting mine.
"""
from docopt import docopt
if __name__ == '__main__':
arguments = docopt(__doc__, version='Naval Fate 2.0')
print(arguments)
Si necesita algo rápido y no muy flexible
main.py:
import sys
first_name = sys.argv[1]
last_name = sys.argv[2]
print("Hello " + first_name + " " + last_name)
Luego ejecute python main.py James Smith
para producir el siguiente resultado:
Hola James Smith
#set default args as -h , if no args:
if len(sys.argv) == 1: sys.argv[1:] = ["-h"]
Yo mismo uso optparse, pero me gusta mucho la dirección que está tomando Simon Willison con su optfunc biblioteca. Funciona por:
" introspección de una función definición (incluidos sus argumentos y sus valores predeterminados) y usando que para construir una línea de comando analizador de argumentos. "
Entonces, por ejemplo, esta definición de función:
def geocode(s, api_key='', geocoder='google', list_geocoders=False):
se convierte en este texto de ayuda de optparse:
Options:
-h, --help show this help message and exit
-l, --list-geocoders
-a API_KEY, --api-key=API_KEY
-g GEOCODER, --geocoder=GEOCODER
Me gusta getopt de stdlib, por ejemplo:
try:
opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
except getopt.GetoptError, err:
usage(err)
for opt, arg in opts:
if opt in ('-h', '--help'):
usage()
if len(args) != 1:
usage("specify thing...")
Últimamente he estado envolviendo algo similar a esto para hacer que las cosas sean menos detalladas (por ejemplo, hacer implícito "-h").
Pocoo click es más intuitivo, requiere menos repetitivo y es al menos tan poderoso como argparse.
La única debilidad que he encontrado hasta ahora es que no se puede hacer mucha personalización para ayudar a las páginas, pero eso generalmente no es un requisito y docopt parece ser la opción clara cuando lo es.
Puede que le interese un pequeño módulo de Python que escribí para facilitar el manejo de los argumentos de la línea de comandos (código abierto y uso gratuito) - Comando
Recomiendo mirar docopt como una alternativa simple a estos otros.
docopt es un nuevo proyecto que funciona analizando su mensaje de ayuda --en lugar de requerir que implemente todo usted mismo. Solo tiene que poner su mensaje de uso en el formato POSIX.
Otra opción es argh . Se basa en argparse y le permite escribir cosas como:
import argh
# declaring:
def echo(text):
"Returns given word as is."
return text
def greet(name, greeting='Hello'):
"Greets the user with given name. The greeting is customizable."
return greeting + ', ' + name
# assembling:
parser = argh.ArghParser()
parser.add_commands([echo, greet])
# dispatching:
if __name__ == '__main__':
parser.dispatch()
Generará automáticamente ayuda, etc., y puede usar decoradores para proporcionar una guía adicional sobre cómo debería funcionar el análisis arg.
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
Assuming the Python code above is saved into a file called prog.py
$ python prog.py -h
Ref-link: https://docs.python.org/3.3/library/argparse.html
Mi solución es entrypoint2 . Ejemplo:
from entrypoint2 import entrypoint
@entrypoint
def add(file, quiet=True):
''' This function writes report.
:param file: write report to FILE
:param quiet: don't print status messages to stdout
'''
print file,quiet
texto de ayuda:
usage: report.py [-h] [-q] [--debug] file
This function writes report.
positional arguments:
file write report to FILE
optional arguments:
-h, --help show this help message and exit
-q, --quiet don't print status messages to stdout
--debug set logging level to DEBUG