Programação Orientada a Eventos

A programação orientada a eventos concentra-se em eventos. Eventualmente, o fluxo do programa depende de eventos. Até agora, estávamos lidando com um modelo de execução sequencial ou paralelo, mas o modelo com o conceito de programação orientada a eventos é chamado de modelo assíncrono. A programação orientada a eventos depende de um loop de eventos que está sempre ouvindo os novos eventos de entrada. O funcionamento da programação orientada a eventos depende de eventos. Depois que um evento é executado em loop, os eventos decidem o que executar e em que ordem. O fluxograma a seguir ajudará você a entender como isso funciona -

Módulo Python - Asyncio

O módulo Asyncio foi adicionado ao Python 3.4 e fornece infraestrutura para escrever código simultâneo de thread único usando co-rotinas. A seguir estão os diferentes conceitos usados ​​pelo módulo Asyncio -

O loop de eventos

O loop de eventos é uma funcionalidade para manipular todos os eventos em um código computacional. Ele atua durante a execução de todo o programa e acompanha a entrada e a execução de eventos. O módulo Asyncio permite um único loop de evento por processo. A seguir estão alguns métodos fornecidos pelo módulo Asyncio para gerenciar um loop de eventos -

  • loop = get_event_loop() - Este método fornecerá o loop de eventos para o contexto atual.

  • loop.call_later(time_delay,callback,argument) - Este método organiza o retorno de chamada que deve ser chamado após os segundos de time_delay fornecidos.

  • loop.call_soon(callback,argument)- Este método organiza um retorno de chamada que deve ser chamado assim que possível. O retorno de chamada é chamado após call_soon () retornar e quando o controle retornar ao loop de eventos.

  • loop.time() - Este método é usado para retornar a hora atual de acordo com o relógio interno do loop de eventos.

  • asyncio.set_event_loop() - Este método definirá o loop de eventos do contexto atual para o loop.

  • asyncio.new_event_loop() - Este método irá criar e retornar um novo objeto de loop de evento.

  • loop.run_forever() - Este método será executado até que o método stop () seja chamado.

Exemplo

O seguinte exemplo de loop de evento ajuda na impressão hello worldusando o método get_event_loop (). Este exemplo foi retirado da documentação oficial do Python.

import asyncio

def hello_world(loop):
   print('Hello World')
   loop.stop()

loop = asyncio.get_event_loop()

loop.call_soon(hello_world, loop)

loop.run_forever()
loop.close()

Resultado

Hello World

Futuros

Isso é compatível com a classe concurrent.futures.Future que representa um cálculo que não foi realizado. Existem as seguintes diferenças entre asyncio.futures.Future e concurrent.futures.Future -

  • Os métodos result () e exception () não usam um argumento de tempo limite e geram uma exceção quando o futuro ainda não está pronto.

  • Callbacks registrados com add_done_callback () são sempre chamados via call_soon () do loop de evento.

  • A classe asyncio.futures.Future não é compatível com as funções wait () e as_completed () no pacote concurrent.futures.

Exemplo

A seguir está um exemplo que ajudará você a entender como usar a classe asyncio.futures.future.

import asyncio

async def Myoperation(future):
   await asyncio.sleep(2)
   future.set_result('Future Completed')

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
   loop.run_until_complete(future)
   print(future.result())
finally:
   loop.close()

Resultado

Future Completed

Corrotinas

O conceito de co-rotinas no Asyncio é semelhante ao conceito de objeto Thread padrão no módulo de threading. Esta é a generalização do conceito de sub-rotina. Uma co-rotina pode ser suspensa durante a execução para que aguarde o processamento externo e retorne do ponto em que parou quando o processamento externo foi concluído. As duas maneiras a seguir nos ajudam na implementação de corrotinas -

função def assíncrona ()

Este é um método para implementação de co-rotinas no módulo Asyncio. A seguir está um script Python para o mesmo -

import asyncio

async def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

Resultado

First Coroutine

decorador @ asyncio.coroutine

Outro método para implementação de co-rotinas é utilizar geradores com o decorador @ asyncio.coroutine. A seguir está um script Python para o mesmo -

import asyncio

@asyncio.coroutine
def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

Resultado

First Coroutine

Tarefas

Esta subclasse do módulo Asyncio é responsável pela execução de co-rotinas em um loop de eventos de maneira paralela. Seguir o script Python é um exemplo de processamento de algumas tarefas em paralelo.

import asyncio
import time
async def Task_ex(n):
   time.sleep(1)
   print("Processing {}".format(n))
async def Generator_task():
   for i in range(10):
      asyncio.ensure_future(Task_ex(i))
   int("Tasks Completed")
   asyncio.sleep(2)

loop = asyncio.get_event_loop()
loop.run_until_complete(Generator_task())
loop.close()

Resultado

Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9

Transportes

O módulo Asyncio fornece classes de transporte para a implementação de vários tipos de comunicação. Essas classes não são thread-safe e sempre emparelhadas com uma instância de protocolo após o estabelecimento do canal de comunicação.

A seguir estão os diferentes tipos de transportes herdados do BaseTransport -

  • ReadTransport - Esta é uma interface para transportes somente leitura.

  • WriteTransport - Esta é uma interface para transportes somente gravação.

  • DatagramTransport - Esta é uma interface para envio de dados.

  • BaseSubprocessTransport - Semelhante à classe BaseTransport.

A seguir estão cinco métodos distintos da classe BaseTransport que são subsequentemente transitórios entre os quatro tipos de transporte -

  • close() - Fecha o transporte.

  • is_closing() - Este método retornará verdadeiro se o transporte estiver fechando ou já estiver fechado.transports.

  • get_extra_info(name, default = none) - Isso nos dará algumas informações extras sobre o transporte.

  • get_protocol() - Este método retornará o protocolo atual.

Protocolos

O módulo Asyncio fornece classes básicas que você pode criar em subclasses para implementar seus protocolos de rede. Essas classes são usadas em conjunto com transportes; o protocolo analisa os dados de entrada e pede a gravação dos dados de saída, enquanto o transporte é responsável pela E / S e pelo armazenamento em buffer. A seguir estão três classes de protocolo -

  • Protocol - Esta é a classe base para implementar protocolos de streaming para uso com transportes TCP e SSL.

  • DatagramProtocol - Esta é a classe base para implementar protocolos de datagrama para uso com transportes UDP.

  • SubprocessProtocol - Esta é a classe base para implementar protocolos que se comunicam com processos filhos por meio de um conjunto de tubos unidirecionais.