Dos líneas de código para generar una línea de comando para un script de Python

A veces tenemos tal requisito:

Definimos un método de Python, el método acepta algunos parámetros, pero al llamar, queremos exponer estos parámetros en la línea de comando.

Por ejemplo, aquí hay un método de rastreo:

import requests

def scrape(url, timeout=10):
    response = requests.get(url, timeout=timeout)
    print(response.text)

Aquí se define un método de extracción. El primer parámetro recibe la URL, es decir, la URL rastreada, y el segundo parámetro recibe el tiempo de espera, es decir, el tiempo de espera especificado.

Al llamar, podemos llamarlo así:

scrape('https:///www.baidu.com', 10)

Si queremos cambiar los parámetros a la url, tenemos que cambiar el código, ¿no?

Entonces, a veces queremos exponer estos parámetros en la línea de comando. En este momento, podemos usar bibliotecas como argparse, etc. Es muy engorroso declarar cada parámetro uno por uno. El código es el siguiente:

parser = argparse.ArgumentParser(description='Scrape Function')
parser.add_argument('url', type=str,
                    help='an integer for the accumulator')
parser.add_argument('timeout',  type=int,
                    help='sum the integers (default: find the max)')

if __name__ == '__main__':
    args = parser.parse_args()
    scrape(args.url, args.timeout)

Para que podamos usar con éxito la línea de comando para llamar a este script:

python3 main.py https://www.baidu.com 10

¿Se siente muy molesto? argparse apesta y es largo de escribir, y difícil de pensar.

Fuego

Pero a continuación vamos a presentar una biblioteca con la que podemos hacer esto con solo dos líneas de código.

Esta biblioteca, llamada Fire, puede agregar rápidamente soporte de parámetros de línea de comandos a un método o clase de Python.

Primero mire el método de instalación, use pip3 para instalarlo:

pip3 install fire

Así que lo tenemos instalado.

usar

Veamos algunos ejemplos a continuación.

Soporte de método

El primer ejemplo de código es el siguiente:

import fire

def hello(name="World"):
  return "Hello %s!" % name

if __name__ == '__main__':
  fire.Fire(hello)

Aquí definimos un método hello, y luego recibimos un parámetro de nombre, el valor predeterminado es World, y luego generamos la cadena Hello plus name.

Luego importamos la biblioteca fire, llamamos a su método Fire y pasamos la declaración del método hello, ¿qué sucede?

Guardemos este código como demo1.py y ejecútelo con Python3:

python3 demo1.py

Los resultados son los siguientes:

Hello World!

No se ve diferente.

Pero si ejecutamos el siguiente comando en este momento, podemos ver algunas cosas mágicas:

python3 demo1.py --help

Los resultados son los siguientes:

NAME
    demo1.py

SYNOPSIS
    demo1.py <flags>

FLAGS
    --name=NAME
        Default: 'World'

Como puede ver, aquí convierte el parámetro de nombre en un parámetro opcional en la línea de comando, y podemos  —-name reemplazar el parámetro de nombre por.

Intentemos:

python3 demo1.py --name 123

Aquí pasamos un parámetro de nombre de 123, y en este momento encontramos que el resultado de ejecución se convierte en el siguiente:

Hello 123!

¿Es muy conveniente? Facilitamos la compatibilidad y el reemplazo de los argumentos de la línea de comandos sin argparse.

¿Qué sucede si cancelamos el valor predeterminado del parámetro de nombre? El código se reescribe de la siguiente manera:

import fire

def hello(name):
  return "Hello %s!" % name

if __name__ == '__main__':
  fire.Fire(hello)

En este punto, vuelva a ejecutar:

python3 demo1.py --help

Puedes ver que el resultado se convierte en el siguiente:

NAME
    demo1.py

SYNOPSIS
    demo1.py NAME

POSITIONAL ARGUMENTS
    NAME

NOTES
    You can also use flags syntax for POSITIONAL ARGUMENTS

En este momento, encontramos que el parámetro de nombre se ha convertido en un parámetro obligatorio. Debemos especificar el contenido de este parámetro en la línea de comando, y la llamada se convertirá en el siguiente comando:

python3 demo1.py 123

El resultado sigue siendo el mismo.

apoyo de clase

Por supuesto, la biblioteca de incendios no solo admite la adición de soporte de línea de comandos a los métodos, sino que también admite la adición de soporte de línea de comandos a una clase.

Veamos otro ejemplo:

import fire

class Calculator(object):    
    def double(self, number):
        return 2 * number

if __name__ == '__main__':
    fire.Fire(Calculator)

Guardamos este código como demo2.py y ejecutamos:

python3 demo2.py

Los resultados son los siguientes:

NAME
    demo2.py

SYNOPSIS
    demo2.py COMMAND

COMMANDS
    COMMAND is one of the following:

     double

Como puede ver, aquí reconoce los métodos en la clase Calculadora, uno de los COMANDOS es doble, intentemos llamar:

python3 demo2.py double

Los resultados son los siguientes:

ERROR: The function received no value for the required argument: number
Usage: demo2.py double NUMBER

For detailed information on this command, run:
  demo2.py double --help

Como dije aquí, se debe especificar otro parámetro aquí, llamado NÚMERO. Al mismo tiempo, este parámetro sigue siendo un parámetro obligatorio. Intentemos agregar:

python3 demo2.py double 4

Los resultados son los siguientes:

8

En este momento, se puede lograr el resultado correcto.

Entonces, en general, fire puede ser una línea de comando de clase, cada comando corresponde al nombre de un método, y se agregan parámetros adicionales opcionales o requeridos al final de los parámetros de la línea de comando.

volver a escribir

Finalmente, regresemos y agreguemos compatibilidad con argumentos de línea de comandos al método de extracción que definimos al principio:

import requests
import fire

def scrape(url, timeout=10):
    response = requests.get(url, timeout=timeout)
    print(response.text)
    
    
if __name__ == '__main__':
    fire.Fire(scrape)

¡eso es todo! ¿Es muy conveniente guardar el extenso código argparse?

La llamada es de la forma:

NAME
    main.py

SYNOPSIS
    main.py URL <flags>

POSITIONAL ARGUMENTS
    URL

FLAGS
    --timeout=TIMEOUT
        Default: 10

Como se mencionó aquí, la URL es un parámetro obligatorio y el tiempo de espera es un parámetro opcional.

Finalmente llama a lo siguiente:

python3 main.py https://www.baidu.com 

De esta forma podemos pasar fácilmente la url a través de la línea de comandos.

Por supuesto, el tiempo de espera sigue siendo un valor opcional. Podemos  —-timeout especificar el parámetro de tiempo de espera de la siguiente manera:

python3 main.py https://www.baidu.com --timeout 5

De esta forma, ambos parámetros se pueden asignar con éxito y el efecto final es rastrear Baidu, con un tiempo de espera de 5 segundos.

¿Qué tal? ¿Es conveniente? ¡Usémoslo! Amigos que están aprendiendo programación y Python, es muy difícil que una persona aprenda de la oscuridad. El blogger también es una persona pasada. Aquí hay un nuevo grupo de deducción: 1020465983, que ha preparado recursos de aprendizaje y proyectos divertidos para todos. Bienvenidos todos a unirse y comunicarse.

Supongo que te gusta

Origin blog.csdn.net/weixin_56659172/article/details/124144207
Recomendado
Clasificación