Pacotes PyPI
Em junho de 2020, esses são os pacotes relacionados ao evento disponíveis no PyPI, ordenados pela data de lançamento mais recente.
Tem mais
É possível escolher entre várias bibliotecas, usando terminologias muito diferentes (eventos, sinais, manipuladores, envio de métodos, ganchos, ...).
Estou tentando manter uma visão geral dos pacotes acima, além das técnicas mencionadas nas respostas aqui.
Primeiro, alguma terminologia ...
Padrão de observador
O estilo mais básico do sistema de eventos é o 'método bag of handler', que é uma implementação simples do padrão Observer .
Basicamente, os métodos do manipulador (chamadas) são armazenados em uma matriz e são chamados quando o evento é acionado.
Publicar-Assinar
A desvantagem dos sistemas de eventos do Observer é que você só pode registrar os manipuladores no objeto Event (ou lista de manipuladores) real. Portanto, no momento da inscrição, o evento já precisa existir.
É por isso que existe o segundo estilo de sistemas de eventos: o
padrão de publicação-assinatura . Aqui, os manipuladores não se registram em um objeto de evento (ou lista de manipuladores), mas em um distribuidor central. Os notificadores também conversam apenas com o despachante. O que ouvir ou o que publicar é determinado por 'sinal', que nada mais é do que um nome (string).
Padrão do mediador
Também pode ser interessante: o padrão do Mediador .
Hooks
Um sistema de 'gancho' é usado geralmente no contexto de plugins de aplicativos. O aplicativo contém pontos de integração fixos (ganchos), e cada plug-in pode se conectar a esse gancho e executar determinadas ações.
Outros eventos'
Nota: threading.Event não é um 'sistema de eventos' no sentido acima. É um sistema de sincronização de threads em que um thread aguarda até que outro thread 'sinalize' o objeto Event.
As bibliotecas de mensagens de rede geralmente também usam o termo 'eventos'; às vezes, esses conceitos são semelhantes; às vezes não. É claro que eles podem atravessar fronteiras de processos, processos e computadores. Veja, por exemplo
, pyzmq , pymq ,
Twisted , Tornado , gevent , eventlet .
Referências fracas
No Python, manter uma referência a um método ou objeto garante que ele não seja excluído pelo coletor de lixo. Isso pode ser desejável, mas também pode levar a vazamentos de memória: os manipuladores vinculados nunca são limpos.
Alguns sistemas de eventos usam referências fracas em vez de regulares para resolver isso.
Algumas palavras sobre as várias bibliotecas
Sistemas de eventos no estilo observador:
- O zope.event mostra o básico de como isso funciona (veja a resposta de Lennart ). Nota: este exemplo nem suporta argumentos do manipulador.
- A implementação da lista de chamadas do LongPoke mostra que esse sistema de eventos pode ser implementado de forma muito minimalista por subclassificação
list
.
- A variação de Felk EventHook também garante as assinaturas de callees e chamadores.
- O EventHook do spassig (padrão de evento de Michael Foord) é uma implementação direta.
- A aula de Josip's Valued Lessons Event é basicamente a mesma, mas usa um em
set
vez de um list
para armazenar a sacola e implementos __call__
que são adições razoáveis.
- O PyNotify é similar em conceito e também fornece conceitos adicionais de variáveis e condições ('evento alterado da variável'). A página inicial não está funcional.
- axel é basicamente um saco de manipuladores com mais recursos relacionados a rosqueamento, tratamento de erros, ...
- O python-dispatch exige que as classes de origem pares sejam derivadas
pydispatch.Dispatcher
.
- O buslane é baseado em classes, suporta manipuladores únicos ou múltiplos e facilita dicas de tipo extensas.
- O Observador / Evento do Pithikos é um design leve.
Bibliotecas de publicação / assinatura:
- O pisca - pisca possui alguns recursos interessantes, como desconexão automática e filtragem com base no remetente.
- O PyPubSub é um pacote estável e promete "recursos avançados que facilitam a depuração e manutenção de tópicos e mensagens".
- pymitter é uma porta Python do Node.js EventEmitter2 e oferece namespaces, curingas e TTL.
- O PyDispatcher parece enfatizar a flexibilidade em relação à publicação muitos-para-muitos etc. Suporta referências fracas.
- louie é um PyDispatcher reformulado e deve funcionar "em uma ampla variedade de contextos".
- O pypydispatcher é baseado no PyDispatcher (você adivinhou ...) e também funciona no PyPy.
- O django.dispatch é um PyDispatcher reescrito "com uma interface mais limitada, mas com maior desempenho".
- pyeventdispatcher é baseado no event-dispatcher da estrutura PHP do Symfony.
- O dispatcher foi extraído do django.dispatch, mas está ficando bastante antigo.
- O EventManger de Cristian Garcia é uma implementação muito curta.
Outras:
- O pluggy contém um sistema de gancho usado pelos
pytest
plugins.
- O RxPy3 implementa o padrão Observável e permite mesclar eventos, repetir etc.
- Os sinais e slots do Qt estão disponíveis no PyQt
ou PySide2 . Eles funcionam como retorno de chamada quando usados no mesmo encadeamento ou como eventos (usando um loop de eventos) entre dois encadeamentos diferentes. Sinais e Slots têm a limitação de que eles só funcionam em objetos de classes derivadas
QObject
.