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!