¡Explique async y await en detalle, y lo llevará a comprender la postura correcta de Playwright para usar métodos asincrónicos!

En el proceso de usar python para realizar pruebas automatizadas de dramaturgos, definitivamente encontrará el siguiente uso asíncrono

async def func():
      await api
      await api

Es posible que muchos estudiantes solo escriban el código de prueba automatizado del proyecto de acuerdo con esta forma de escritura, y es posible que no entiendan los detalles específicos.Hoy hablaré sobre los detalles técnicos relacionados con el uso asincrónico de dramaturgo. Se recomienda que copie el script en el documento y lo ejecute, ¡el efecto de aprendizaje será mejor!

El concepto de síncrono y asíncrono.

Síncrono: envíe una solicitud, espere la devolución y luego envíe la siguiente solicitud
Asíncrono: envíe una solicitud, no espere la devolución, puede enviar la próxima solicitud en cualquier momento

asíncrono y espera

Python introdujo async y await después de 3.5 para fortalecer su propia programación asincrónica y mejorar la eficiencia. async es la abreviatura de asíncrono y await puede considerarse como la abreviatura de espera asíncrona. async se usa para declarar que una función es asíncrona, y await se usa para esperar a que se complete un método asíncrono. La característica de una función asíncrona es que se puede suspender durante la ejecución de la función para ejecutar otras funciones asíncronas y luego volver para continuar con la ejecución después de que finaliza la condición de suspensión. La función de await es suspender la función y esperar a que se complete la operación de la función. En este momento, regrese y ejecute otras funciones asincrónicas en lugar de esperar estúpidamente. Una vez que se complete la ejecución suspendida, regresará de otras funciones asincrónicas y ejecutará la función suspendida. await solo se puede usar para funciones asincrónicas y se informará un error cuando se usen funciones ordinarias. La esencia de await se realiza a través de yield from, y los puntos de conocimiento relacionados con el generador de rendimiento no se presentarán en detalle aquí.

Por ejemplo: dos programas asincrónicos async a, async b:

Hay await en un paso de a, cuando el programa encuentra la palabra clave await, el programa asíncrono a cuelga para ejecutar el programa asíncrono b (equivalente a saltar de una función para ejecutar otras funciones); cuando finaliza la condición de suspensión, independientemente de b Ya sea que la ejecución se complete o no, salte del programa b inmediatamente, regrese al programa original a para ejecutar la operación original; si la función b seguida de await no es una función asíncrona, entonces la operación solo puede esperar b para terminar de ejecutarse antes de regresar, y no se puede ejecutar en b Return en el proceso, lo que equivale a llamar directamente a la función b, y no es necesario usar la palabra clave await. Por lo tanto, await le sigue una función asíncrona.

Por ejemplo

import time
import asyncio
async def wait1():
    print('wait1 start')
    await asyncio.sleep(1)
    print('wait1 end')

async def wait3():
    print('wait3 start')
    await asyncio.sleep(3)
    print('wait3 end')

async def wait5():

    print('wait5 start')
    await asyncio.sleep(5)
    print('wait5 end')

# 2. 将异步函数加入事件队列

tasks = [
    wait1(),
    wait3(),
    wait5(),
]

if __name__ == '__main__':

    # 创建一个事件循环
    loop = asyncio.get_event_loop()
    startTime = time.time()
    # 执行队列实践,直到最晚的一个事件被处理完毕后结束
    loop.run_until_complete(asyncio.wait(tasks))
    # 如果不在使用loop,建议使用关闭,类似操作文件的close()函数
    loop.close()
    endTime = time.time()
    print("sum time: ",endTime-startTime)

resultado de la operación

esperar5 empezar

esperar3 empezar

espera1 inicio

espera1 fin

esperar3 final

esperar5 final

tiempo de suma: 5.000609874725342

Puede ejecutar el código anterior varias veces y encontraremos que no importa qué función esperar1, esperar3 o esperar5 se ejecute primero, el orden del final final debe ser esperar1>esperar3>esperar5. El tiempo de ejecución total es de unos 5 s, lo que prueba plenamente que las tres funciones se ejecutan en paralelo.

A continuación, podemos modificar el código de la siguiente manera:

async def wait3():
    print('wait3 start')
    time.sleep(3)
    print('wait3 end')

Luego ejecute el código nuevamente, el resultado es el siguiente:

esperar5 empezar

esperar3 empezar

esperar3 final

espera1 inicio

espera1 fin

esperar5 final

tiempo de suma: 5.002418518066406

Descubrirá que solo después de que finalice wait3, aparecerán wait1 end y wait5 end(), lo que prueba bien la declaración anterior: si la función b seguida de await no es una función asíncrona, entonces la operación solo puede esperar a que b termine ejecutar Return no se puede devolver durante la ejecución de b, lo que equivale a llamar directamente a la función b, y no es necesario utilizar la palabra clave await. Podemos ajustar el orden de ejecución de las tareas arbitrariamente, por ejemplo:

tasks = [
    wait1(),
    wait5(),
    wait3(),
]

La ejecución más lenta es que el primer inicio de wait3 espera el final de wait3 antes de ejecutar wait1 o wait5

esperar3 empezar

esperar3 final

esperar5 empezar

espera1 inicio

espera1 fin

esperar5 final

tiempo de suma: 8.000799894332886

un error fácil

Cuando agregamos await al método de sincronización, se informará un error cuando se ejecuta el código, es decir, es incorrecto escribir el script de dramaturgo de la siguiente manera, ¡porque sync_playwright() es un método de sincronización!

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
 browser = p.chromium.launch(channel="chrome")
 page = browser.new_page()
 await page.goto("http://www.baidu.com")
 print(page.title())
 browser.close()

Postura correcta del dramaturgo para usar métodos asincrónicos

El siguiente código se ejecutará con normalidad y el orden de ejecución del script puede garantizarse con await

async def playwright_async_demo():
  async with async_playwright() as p:
     browser = await p.chromium.launch(channel="chrome")
     page = await browser.new_page()
     await page.goto("http://www.baidu.com")
asyncio.run(playwright_async_demo())

Si eliminamos la palabra clave await de browser = await p.chromium.launch(channel= "chrome" ) en el código anterior, se informará un error

página = esperar navegador.nueva_pagina()

AttributeError: el objeto 'coroutine' no tiene atributo 'new_page'

sys: 1: Advertencia de tiempo de ejecución: nunca se esperó la corrutina 'BrowserType.launch'

La razón es que la línea de código browser = p.chromium.launch(channel= "chrome" ) se ejecuta antes de la siguiente línea page = await browser.new_page()

El resumen final, si necesita ejecutar casos de uso en paralelo, debe considerar async (aquí se recomienda según el diseño del escenario), si no existe tal requisito, esta parte es solo para comprender.

¡Cada artículo mío espera ayudar a los lectores a resolver los problemas que se encuentran en el trabajo real! Si el artículo te ayudó, dale me gusta, marca, ¡adelante! ¡Tu aliento es mi mayor motivación para seguir actualizando artículos!

 

Supongo que te gusta

Origin blog.csdn.net/liwenxiang629/article/details/130555814
Recomendado
Clasificación