Paket PyPI
Pada Juni 2020, ini adalah paket terkait acara yang tersedia di PyPI, dipesan oleh tanggal rilis terbaru.
Masih ada lagi
Itu banyak perpustakaan untuk dipilih, menggunakan terminologi yang sangat berbeda (peristiwa, sinyal, penangan, pengiriman metode, kait, ...).
Saya mencoba untuk menjaga ikhtisar paket di atas, ditambah teknik yang disebutkan dalam jawaban di sini.
Pertama, beberapa terminologi ...
Pola pengamat
Gaya paling dasar dari sistem acara adalah 'metode kantong penangan', yang merupakan implementasi sederhana dari pola Observer .
Pada dasarnya, metode handler (callable) disimpan dalam array dan masing-masing dipanggil ketika acara 'kebakaran'.
Publikasikan-Berlangganan
Kerugian dari sistem acara Pengamat adalah bahwa Anda hanya dapat mendaftarkan penangan pada objek Acara yang sebenarnya (atau daftar penangan). Jadi pada saat pendaftaran acara sudah perlu ada.
Karena itulah ada gaya kedua sistem acara: pola
terbitkan-berlangganan . Di sini, penangan tidak mendaftar pada objek acara (atau daftar penangan), tetapi pada pengirim pusat. Pemberitahu juga hanya berbicara dengan operator. Apa yang harus didengarkan, atau apa yang akan diterbitkan ditentukan oleh 'sinyal', yang tidak lebih dari sebuah nama (string).
Pola mediator
Mungkin juga menarik: pola Mediator .
Kait
Sistem 'hook' biasanya digunakan dalam konteks plugin aplikasi. Aplikasi berisi titik integrasi tetap (kait), dan setiap plugin dapat terhubung ke kait itu dan melakukan tindakan tertentu.
'Acara' lainnya
Catatan: threading.Event bukan 'sistem acara' dalam arti di atas. Ini adalah sistem sinkronisasi utas di mana satu utas menunggu hingga utas lain 'memberi sinyal' pada objek Peristiwa.
Perpustakaan perpesanan jaringan sering menggunakan istilah 'acara' juga; terkadang konsepnya serupa; terkadang tidak. Mereka tentu saja dapat melintasi batas thread, proses, dan komputer. Lihat misalnya
pyzmq , pymq ,
Twisted , Tornado , gevent , eventlet .
Referensi yang lemah
Dalam Python, memegang referensi ke metode atau objek memastikan bahwa itu tidak akan dihapus oleh pengumpul sampah. Ini dapat diinginkan, tetapi juga dapat menyebabkan kebocoran memori: penangan yang terhubung tidak pernah dibersihkan.
Beberapa sistem acara menggunakan referensi yang lemah alih-alih yang biasa untuk menyelesaikannya.
Beberapa kata tentang berbagai perpustakaan
Sistem acara bergaya pengamat:
- zope.event menunjukkan tulang kosong bagaimana ini bekerja (lihat jawaban Lennart ). Catatan: contoh ini bahkan tidak mendukung argumen penangan.
- Implementasi 'callable list' LongPoke menunjukkan bahwa sistem acara seperti itu dapat diimplementasikan dengan sangat minimalis dengan subklasifikasi
list
.
- Variasi Felk, EventHook juga memastikan tanda tangan callees dan penelepon.
- EventHook spassig (Pola Acara Michael Foord) adalah implementasi langsung.
- Kelas Event Pelajaran Nilai Josip pada dasarnya sama, tetapi menggunakan
set
bukan list
untuk menyimpan tas, dan mengimplementasikan __call__
yang merupakan tambahan yang masuk akal.
- PyNotify serupa dalam konsep dan juga menyediakan konsep-konsep tambahan tentang variabel dan kondisi ('variabel berubah acara'). Beranda tidak berfungsi.
- axel pada dasarnya adalah kantung penanganan dengan lebih banyak fitur yang terkait dengan threading, penanganan kesalahan, ...
- python-dispatch membutuhkan kelas sumber genap untuk diturunkan
pydispatch.Dispatcher
.
- buslane berbasis kelas, mendukung penangan tunggal atau ganda dan memfasilitasi petunjuk jenis yang luas.
- Pengamat / Acara Pithikos adalah desain yang ringan.
Publikasikan-berlangganan perpustakaan:
- blinker memiliki beberapa fitur bagus seperti pemutusan sambungan otomatis dan penyaringan berdasarkan pengirim.
- PyPubSub adalah paket stabil, dan menjanjikan "fitur-fitur canggih yang memfasilitasi debugging dan menjaga topik dan pesan".
- pymitter adalah port Python dari Node.js EventEmitter2 dan menawarkan ruang nama, wildcard, dan TTL.
- PyDispatcher tampaknya menekankan fleksibilitas sehubungan dengan publikasi banyak ke banyak dll. Mendukung referensi yang lemah.
- Louie adalah PyDispatcher yang dikerjakan ulang dan harus bekerja "dalam berbagai konteks".
- pypydispatcher didasarkan pada (Anda dapat menebaknya ...) PyDispatcher dan juga berfungsi di PyPy.
- django.dispatch adalah PyDispatcher yang ditulis ulang "dengan antarmuka yang lebih terbatas, tetapi kinerjanya lebih tinggi".
- pyeventdispatcher didasarkan pada event-dispatcher framework PHP milik Symfony.
- dispatcher diekstraksi dari django.dispatch tetapi semakin tua.
- EventManger Cristian Garcia adalah implementasi yang sangat singkat.
Lainnya:
- Pluggy berisi sistem kait yang digunakan oleh
pytest
plugin.
- RxPy3 mengimplementasikan pola yang Dapat Diamati dan memungkinkan penggabungan acara, coba lagi dll.
- Sinyal dan Slot Qt tersedia dari PyQt
atau PySide2 . Mereka berfungsi sebagai callback ketika digunakan di utas yang sama, atau sebagai peristiwa (menggunakan loop peristiwa) antara dua utas yang berbeda. Sinyal dan Slot memiliki batasan bahwa mereka hanya bekerja pada objek dari kelas yang berasal
QObject
.
Saya telah melakukannya dengan cara ini:
Namun, seperti semua yang saya lihat, tidak ada pydoc yang dibuat secara otomatis untuk ini, dan tidak ada tanda tangan, yang benar-benar menyebalkan.
sumber
_bag_of_handlers
yang merupakan daftar. Metode add kelas hanya akan menjadiself._bag_of_handlers.append(some_callable)
. Metode api kelas akan mengulang melalui `_bag_of_handlers` melewati args dan kwargs yang disediakan ke handler dan mengeksekusi masing-masing secara berurutan.Kami menggunakan EventHook seperti yang disarankan dari Michael Foord dalam Pola Kegiatannya :
Cukup tambahkan EventHooks ke kelas Anda dengan:
Kami menambahkan fungsionalitas untuk menghapus semua pendengar dari objek ke kelas Michaels dan berakhir dengan ini:
sumber
self.__handlers = [h for h in self._handlers if getattr(h, 'im_self', False) != obj]
Saya menggunakan zope.event . Ini adalah tulang paling telanjang yang bisa Anda bayangkan. :-) Sebenarnya, ini adalah kode sumber lengkap:
Perhatikan bahwa Anda tidak dapat mengirim pesan antar proses, misalnya. Ini bukan sistem pesan, hanya sistem acara, tidak lebih, tidak kurang.
sumber
Saya menemukan skrip kecil ini di Valued Lessons . Tampaknya memiliki kesederhanaan / rasio daya yang tepat yang saya cari. Peter Thatcher adalah penulis kode berikut (tidak ada lisensi yang disebutkan).
sumber
Berikut ini adalah desain minimal yang harus bekerja dengan baik. Yang harus Anda lakukan adalah mewarisi
Observer
kelas dan kemudian menggunakannyaobserve(event_name, callback_fn)
untuk mendengarkan acara tertentu. Kapan saja peristiwa spesifik itu dipecat di mana saja dalam kode (mis.Event('USB connected')
), Panggilan balik yang sesuai akan menyala.Contoh:
sumber
Saya membuat
EventManager
kelas (kode di akhir). Sintaksnya adalah sebagai berikut:Berikut ini sebuah contoh:
Keluaran:
Kode EventManger:
sumber
Anda mungkin melihat pymitter ( pypi ). Ini adalah satu file kecil (~ 250 loc) pendekatan "menyediakan ruang nama, wildcard dan TTL".
Inilah contoh dasar:
sumber
Saya membuat variasi dari pendekatan minimalis Longpoke yang juga memastikan tanda tangan untuk callees dan penelepon:
sumber
Jika saya melakukan kode di pyQt saya menggunakan paradigma QT soket / sinyal, hal yang sama juga berlaku untuk Django
Jika saya melakukan I / OI async gunakan modul pilih asli
Jika saya menggunakan parser SAX python, saya menggunakan API acara yang disediakan oleh SAX. Jadi sepertinya saya korban API yang mendasarinya :-)
Mungkin Anda harus bertanya pada diri sendiri apa yang Anda harapkan dari kerangka / modul acara. Preferensi pribadi saya adalah menggunakan paradigma Socket / Sinyal dari QT. info lebih lanjut tentang itu dapat ditemukan di sini
sumber
Berikut modul lain untuk dipertimbangkan. Tampaknya pilihan yang layak untuk aplikasi yang lebih banyak menuntut.
sumber
Jika Anda ingin melakukan hal-hal yang lebih rumit seperti menggabungkan acara atau coba lagi, Anda dapat menggunakan pola Observable dan perpustakaan dewasa yang mengimplementasikannya. https://github.com/ReactiveX/RxPY . Dapat diamati sangat umum dalam Javascript dan Java dan sangat nyaman digunakan untuk beberapa tugas async.
OUTPUT :
sumber
Jika Anda memerlukan eventbus yang berfungsi melintasi batas proses atau jaringan, Anda dapat mencoba PyMQ . Saat ini mendukung pub / sub, antrian pesan dan RPC sinkron. Versi default berfungsi di atas backend Redis, jadi Anda memerlukan server Redis yang sedang berjalan. Ada juga backend dalam memori untuk pengujian. Anda juga dapat menulis backend Anda sendiri.
Untuk menginisialisasi sistem:
Penafian: Saya penulis perpustakaan ini
sumber
Anda dapat mencoba
buslane
modul.Perpustakaan ini membuat implementasi sistem berbasis pesan lebih mudah. Ini mendukung perintah (penangan tunggal) dan pendekatan peristiwa (0 atau beberapa penangan). Buslane menggunakan anotasi jenis Python untuk mendaftarkan handler dengan benar.
Contoh sederhana:
Untuk menginstal buslane, cukup gunakan pip:
sumber
Beberapa waktu lalu saya sudah menulis perpustakaan yang mungkin berguna untuk Anda. Ini memungkinkan Anda untuk memiliki pendengar lokal dan global, berbagai cara untuk mendaftarkan mereka, prioritas eksekusi dan sebagainya.
Silahkan lihat pyeventdispatcher
sumber