python - ¿Cuál es la diferencia principal entre asyncio y trío?
asynchronous python-asyncio (1)
De dónde vengo: soy el autor principal de trío. También soy uno de los principales contribuyentes a la curiosidad (y escribí el artículo sobre el que te vinculas), y un desarrollador central de Python que ha estado muy involucrado en las discusiones sobre cómo mejorar asyncio.
No estoy seguro de lo que quieres decir con las devoluciones de llamada. En trío (y curio), uno de los principios básicos del diseño es que nunca se programa con devoluciones de llamada; se siente más como la programación basada en hilos que en la programación basada en devolución de llamada. Supongo que si abres el capó y miras cómo se implementan internamente, entonces hay lugares donde usan devoluciones de llamada, o cosas que son equivalentes a las devoluciones de llamada si entrecierras los ojos. Pero eso es como decir que Python y C son equivalentes porque el intérprete de Python está implementado en C. Nunca se utilizan devoluciones de llamada.
De todas formas:
Trio vs asyncio
Asyncio es mas maduro
La primera gran diferencia es la madurez del ecosistema. Cuando escribo esto en marzo de 2018 , hay muchas más bibliotecas con soporte de asyncio que con trío. Por ejemplo, en este momento no hay servidores HTTP reales con soporte de trío. El clasificador Framework :: AsyncIO en PyPI tiene actualmente 122 bibliotecas, mientras que el clasificador Framework :: Trio solo tiene 8. Espero que esta parte de la respuesta quede desactualizada rápidamente, por ejemplo, aquí está Kenneth Reitz experimentando con la adición de compatibilidad con trío en la próxima versión de las solicitudes , pero ahora mismo, debe esperar que si es trío por algo complicado, se encontrará con las piezas faltantes que debe completar usted mismo en lugar de tomar una biblioteca de pypi , o que necesitará usar el paquete trio-asyncio que le permite usar las bibliotecas asyncio en los programas de trio . (El canal de chat de trío es útil para averiguar qué hay disponible y en qué están trabajando otras personas).
Trio hace tu código más simple
En términos de las bibliotecas reales, también son muy diferentes. El principal argumento para trio es que hace que la escritura de código concurrente sea mucho más simple que usar asyncio. Por supuesto, ¿cuándo fue la última vez que escuchó a alguien decir que su biblioteca hace que las cosas sean más difíciles de usar? Déjeme dar un ejemplo concreto. En esta charla ( slides ), utilizo el ejemplo de la implementación de RFC 8305 "Happy Eyeballs" , que es un algoritmo concurrente simple que se utiliza para establecer una conexión de red de manera eficiente. Esto es algo en lo que Glyph ha estado pensando durante años, y su última versión para Twisted tiene alrededor de 600 líneas. (Asyncio sería casi lo mismo; Twisted y asyncio son muy similares desde el punto de vista arquitectónico). En la charla, te enseño todo lo que necesitas saber para implementarlo en <40 líneas usando trío (y solucionamos un error en su versión mientras nosotros re en eso). Entonces, en este ejemplo, usar trío literalmente hace que nuestro código sea un orden de magnitud más simple.
También puede encontrar interesantes estos comentarios de los usuarios: 1 , 2 , 3
Hay muchas muchas diferencias en detalle
¿Por qué pasó esto? Esa es una respuesta mucho más larga :-). Estoy trabajando gradualmente en escribir las diferentes piezas en las publicaciones y charlas del blog, y trataré de recordar actualizar esta respuesta con enlaces a medida que estén disponibles. Básicamente, todo depende de que Trio tenga un pequeño conjunto de primitivas cuidadosamente diseñadas que tienen algunas diferencias fundamentales con respecto a cualquier otra biblioteca que conozca (aunque, por supuesto, a partir de ideas de muchos lugares). Aquí hay algunas notas al azar para darle una idea:
Un problema muy, muy común en asyncio y bibliotecas relacionadas es que llama a some_function()
, y regresa, por lo que cree que está hecho, pero en realidad aún se está ejecutando en segundo plano. Esto conduce a todo tipo de errores complicados, ya que dificulta el control del orden en el que suceden las cosas, o saber cuándo algo realmente ha terminado, y puede ocultar problemas directamente porque si una tarea en segundo plano falla con una excepción no controlada, asyncio Generalmente solo imprime algo en la consola y luego sigue adelante. En trío, la forma en que manejamos la generación de tareas a través de "viveros" significa que no ocurre nada de lo siguiente: cuando una función regresa, entonces sabes que está terminada, y actualmente Trio es la única biblioteca de concurrencia para Python donde las excepciones siempre se propagan hasta que las detectas.
La forma en que Trio gestiona los tiempos de espera y las cancelaciones es novedosa, y creo que es mejor que los sistemas de vanguardia anteriores como C # y Golang. En realidad escribí un ensayo completo sobre esto, por lo que no voy a entrar en todos los detalles aquí. Pero el sistema de cancelación de asyncio, o en realidad, los sistemas, tiene dos de ellos con una semántica ligeramente diferente, se basan en un conjunto de ideas más antiguo que incluso C # y Golang, y son difíciles de usar correctamente. (Por ejemplo, es fácil que el código "escape" accidentalmente a una cancelación al generar una tarea en segundo plano; consulte el párrafo anterior).
Hay un montón de cosas redundantes en asyncio, que pueden hacer que sea difícil saber qué usar cuando . Tienes futuros, tareas y corrutinas, que se usan básicamente para el mismo propósito, pero necesitas conocer las diferencias entre ellas. Si desea implementar un protocolo de red, debe elegir si utilizar la capa de protocolos / transportes o la capa de flujos, y ambos tienen dificultades difíciles (de esto se trata la primera parte del ensayo que vinculó ).
Actualmente, Trio es la única biblioteca de concurrencia para Python donde control-C simplemente funciona de la manera que usted espera (es decir, aumenta KeyboardInterrupt
donde sea que esté su código). Es una cosa pequeña, pero hace una gran diferencia :-). Por varias razones, no creo que esto se pueda arreglar en asyncio.
Resumiendo
Si necesita enviar algo a producción la próxima semana, entonces debe usar asyncio (o Twisted o Tornado o gevent, que son aún más maduros). Tienen grandes ecosistemas, otras personas los han usado en la producción antes que usted, y no van a ninguna parte.
Si intentar usar esos marcos te deja frustrado y confundido, o si quieres experimentar con una forma diferente de hacer las cosas, entonces definitivamente echa un vistazo al trío: somos amigos :-).
Si quiere enviar algo a producción en un año a partir de ahora ... entonces no estoy seguro de qué decirle. La concurrencia de Python está en flujo. Trio tiene muchas ventajas a nivel de diseño, pero ¿es eso suficiente para superar la ventaja inicial de Asyncio? ¿Será asyncio estar en la biblioteca estándar una ventaja o una desventaja? (Observe cómo en estos días todo el mundo usa requests
, aunque la biblioteca estándar tiene urllib .) ¿Cuántas de las nuevas ideas en trío se pueden agregar a asyncio? Nadie sabe. Espero que haya muchas discusiones interesantes sobre esto en PyCon este año :-).
Hoy, encontré una biblioteca llamada trio que dice que es una API asíncrona para los humanos. Estas palabras son un poco similares con las requests
''. Como las requests
son realmente una buena biblioteca, me pregunto cuáles son las ventajas de trio
.
No hay muchos artículos al respecto, acabo de encontrar un article trata sobre curio
y asyncio
. Para mi sorpresa, el trio
dice que sí mismo es incluso mejor que curio
( curio
próxima generación).
Después de leer la mitad del artículo, no puedo encontrar la diferencia principal entre estos dos marcos asíncronos. Solo da algunos ejemplos de que la implementación de curio
es más conveniente que la de asyncio
. Pero la estructura subyacente es casi la misma (basada en la devolución de llamada, creo que todo el marco de E / S asíncrono se basa en la devolución de llamada sin excepción).
Entonces, ¿podría alguien darme una razón para aceptar que el trio
o la curio
es mejor que el asyncio
? ¿O explicar más acerca de por qué debería elegir trio
lugar de asyncio
?