¿Cómo se puede aprender Python sin conocer el rendimiento?

Introducción

Es posible que haya escuchado que una función con un rendimiento se llama generador en Python, o no le ha prestado atención.También hay un rendimiento en Python. Si conoce el rendimiento en Python, ¿sabe qué es un generador?

 

El concepto de rendimiento

Para comprender el concepto de rendimiento del generador, primero muestre el concepto de rendimiento con un tema de programación común.

Cómo generar la secuencia de Fibonacci

La secuencia de Fibonacci es una secuencia recursiva muy simple. Excepto por el primer y segundo número, cualquier número puede obtenerse sumando los dos primeros números. Usar un programa de computadora para generar los primeros N números de la secuencia de Fibonacci es un problema muy simple. Algunos amigos basados ​​en Python pueden escribir fácilmente las siguientes funciones:

 

Versión 1: Simplemente genere los primeros N números de la secuencia de Fibonacci

def createNum(count): 
    n, a, b = 0, 0, 1 
    while n < count: 
        print b 
        a, b = b, a + b 
        n = n + 1
createNum(5)

Al ejecutar el código anterior, podemos obtener el siguiente resultado:

1 
1 
2 
3 
5

No hay ningún problema con el resultado de salida, pero el método de escritura en la versión 1 es imprimir los números directamente en la función createNum con print, lo que hará que la reutilización de la función sea deficiente, porque la función createNum devuelve None y otras funciones no pueden obtiene la secuencia numérica generada por la función.

Para mejorar la reutilización de la función createNum, es mejor no imprimir la secuencia numérica directamente, sino devolver una Lista. La siguiente es la segunda versión de la función createNum reescrita:

 

Versión 2: Genere los N números superiores de la secuencia de Fibonacci

def createNum(count): 
    n, a, b = 0, 0, 1 
    L = [] 
    while n < count: 
        L.append(b) 
        a, b = b, a + b 
        n = n + 1 
    return L
 
for n in createNum(5): 
    print n

Los resultados de la Lista devuelta por la función createNum en esta versión son los siguientes:

1 
1 
2 
3 
5

La función createNum reescrita puede cumplir con los requisitos de reutilización devolviendo List, pero al mismo tiempo habrá un problema obvio: la memoria ocupada por la función en operación aumentará con el aumento del recuento de parámetros, si Para controlar el uso de la memoria, Es mejor no usar List para almacenar resultados intermedios, sino iterar a través de objetos iterables. En cada iteración, se devuelve el siguiente valor, por lo que: el espacio de memoria es muy pequeño. Porque devuelve un objeto iterable directamente.

 

Versión 3: use yield para generar los primeros N números de la secuencia de Fibonacci

def createNum(count): 
    n, a, b = 0, 0, 1 
    while n < count: 
        yield b      # 使用 yield
        # print(b) 
        a, b = b, a + b 
        n = n + 1
 
for n in createNum(5): 
    print n

También puede llamar manualmente al método next () de createNum (5) (porque createNum (5) es un objeto generador, que tiene un método next ()), para que podamos ver el flujo de ejecución de createNum más claramente:

 

Versión 4: Proceso de ejecución

def createNum(count): 
    n, a, b = 0, 0, 1 
    while n < count: 
        yield b      # 使用 yield
        # print(b) 
        a, b = b, a + b 
        n = n + 1
 

#使用for循环来执行createNum()函数,它返回一个迭代值,下次迭代从yield语句的下一条语句继续执行
<!--for n in createNum(5): 
    print n-->

#使用next方法来执行createNum()函数,generator(生成器)对象具有next()方法
num = createNum(5)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

Ejecute el código anterior, la salida del resultado es la siguiente:

1
1
2
3
5
Traceback (most recent call last): 
 File "<stdin>", line 1, in <module> 
StopIteration

A partir del resultado de salida, se puede encontrar que se lanza una excepción StopIteration cuando se ejecuta la sexta impresión (siguiente (num)), porque la función ha finalizado cuando se ejecuta la quinta impresión (siguiente (num)) y luego la sexta Cuando print (next (num)), el generador lanza automáticamente la excepción StopIteration, lo que indica que la iteración está completa. En el ciclo for, no hay necesidad de manejar las excepciones de StopIteration y el ciclo terminará normalmente.

 

 

El papel del rendimiento

En pocas palabras, el papel de yield es convertir una función en un generador. La función con yield ya no es una función ordinaria. El intérprete de Python la tratará como un generador. Llamar a createNum (5) no ejecutará la función createNum. En su lugar , devuelve un objeto iterable.

 

Cuando se ejecuta el ciclo for, el código dentro de la función createNum se ejecutará cada vez. Cuando la ejecución alcance el rendimiento b, la función createNum devolverá un valor de iteración. En la siguiente iteración, el código continuará ejecutándose desde la siguiente instrucción de rendimiento b, y la función La variable local se ve exactamente igual que antes de la última ejecución de interrupción, por lo que la función continúa ejecutándose hasta que encuentra rendimiento de nuevo.

 

 

Escenarios de uso de rendimiento

  • Genere datos de forma iterativa (productor, la ventaja es más obvia cuando la cantidad de datos es enorme, no ocupa mucha memoria)

  • Recibir datos (consumidor)

  • Interrupción (tarea cooperativa)

 

para resumir

Una función con un rendimiento es un generador, que es diferente de las funciones ordinarias. Generar un generador se ve como una llamada a una función, pero no ejecutará ningún código de función hasta que se llame a next () en él (en el bucle for, next () es llamado automáticamente)) para iniciar la ejecución. Aunque el flujo de ejecución aún se ejecuta de acuerdo con el flujo de la función, se interrumpirá cada vez que se ejecute una declaración de rendimiento y se devolverá un valor de iteración.La siguiente ejecución continuará desde la siguiente declaración de rendimiento. Parece como si una función fuera interrumpida por rendimiento varias veces durante la ejecución normal, y cada interrupción devolverá el valor de iteración actual a través de rendimiento.

El beneficio del rendimiento es obvio. Reescribir una función en un generador gana capacidad iterativa. En comparación con el uso de una instancia de clase para guardar el estado para calcular el siguiente valor de next (), no solo el código es conciso, sino que el flujo de ejecución es extremadamente claro .

Bienvenido a prestar atención a la cuenta pública de [The Way of Infinite Testing], responder [Recibir recursos] Recursos de
aprendizaje de programación de Python productos secos, automatización de la interfaz de usuario de la aplicación del marco Python + Appium , automatización de la interfaz de usuario web del marco Python + Selenium , automatización de la API del marco Python + Unittest,


Los recursos y códigos se envían gratis ~
Hay un código QR de la cuenta oficial en la parte inferior del artículo, puede escanearlo en WeChat y seguirlo.

Observaciones: Mi cuenta pública personal se ha abierto oficialmente, dedicada al intercambio de tecnología de prueba, que incluye: pruebas de big data, pruebas funcionales, desarrollo de pruebas, automatización de la interfaz API, operación y mantenimiento de pruebas, pruebas de automatización de la interfaz de usuario, etc., búsqueda pública de WeChat cuenta: "Wuliang The Way of Testing", o escanee el código QR a continuación:

 ¡Presta atención y crezcamos juntos!

Supongo que te gusta

Origin blog.csdn.net/weixin_41754309/article/details/113758928
Recomendado
Clasificación