Saya memiliki aplikasi, ditulis dengan Python, yang digunakan oleh audiens yang cukup teknis (ilmuwan).
Saya mencari cara yang baik untuk membuat aplikasi dapat dikembangkan oleh pengguna, yaitu arsitektur scripting / plugin.
Saya mencari sesuatu yang sangat ringan . Sebagian besar skrip, atau plugin, tidak akan dikembangkan dan didistribusikan oleh pihak ketiga dan diinstal, tetapi akan menjadi sesuatu yang dikocok oleh pengguna dalam beberapa menit untuk mengotomatiskan tugas yang berulang, menambah dukungan untuk format file, dll. Jadi plugin harus memiliki kode boilerplate minimum absolut, dan tidak memerlukan 'instalasi' selain menyalin ke folder (jadi sesuatu seperti setuptools entry point, atau arsitektur plugin Zope sepertinya terlalu banyak.)
Apakah sudah ada sistem seperti ini di luar sana, atau proyek apa pun yang menerapkan skema serupa yang harus saya perhatikan untuk ide / inspirasi?
imp
Modul sedang usang dalam mendukungimportlib
mulai dari python 3.4imp.load_module
.module_example.py
:loader.py
:Ini tentu saja "minimal", sama sekali tidak ada pengecekan kesalahan, mungkin masalah keamanan yang tak terhitung jumlahnya, ini tidak terlalu fleksibel - tetapi harus menunjukkan kepada Anda betapa sederhananya sebuah sistem plugin dengan Python bisa ..
Anda mungkin ingin melihat ke modul imp juga, meskipun Anda dapat melakukan banyak hal dengan adil
__import__
,os.listdir
dan beberapa manipulasi string.sumber
def call_plugin(name, *args)
menjadidef call_plugin(name, *args, **kwargs)
, dan kemudianplugin.plugin_main(*args)
keplugin.plugin_main(*args, **kwargs)
imp
tidak digunakan lagiimportlib
Lihat ikhtisar ini di atas kerangka / pustaka plugin yang ada , ini adalah titik awal yang baik. Saya sangat suka yapsy , tetapi itu tergantung pada use-case Anda.
sumber
Meskipun pertanyaan itu sangat menarik, saya pikir itu cukup sulit untuk dijawab, tanpa perincian lebih lanjut. Aplikasi macam apa ini? Apakah ada GUI? Apakah ini alat baris perintah? Seperangkat skrip? Program dengan titik masuk unik, dll ...
Mengingat sedikit informasi yang saya miliki, saya akan menjawab dengan cara yang sangat umum.
Apa artinya Anda harus menambahkan plugin?
Pada praktik kode / desain murni, Anda harus menentukan dengan jelas perilaku / tindakan spesifik apa yang Anda inginkan untuk diperluas oleh pengguna Anda. Identifikasi titik masuk umum / serangkaian fungsi yang akan selalu ditimpa, dan tentukan kelompok dalam tindakan ini. Setelah ini selesai, seharusnya mudah untuk memperpanjang aplikasi Anda,
Contoh menggunakan kait , terinspirasi dari MediaWiki (PHP, tetapi apakah bahasa benar-benar penting?):
Contoh lain, terinspirasi dari lincah. Di sini, ekstensi hanya menambahkan perintah ke hg commandline yang dapat dieksekusi, memperluas perilaku.
Untuk kedua pendekatan, Anda mungkin perlu menginisialisasi dan memfinalisasi untuk ekstensi Anda. Anda bisa menggunakan antarmuka umum yang harus diimplementasikan oleh semua ekstensi Anda (lebih cocok dengan pendekatan kedua; mercurial menggunakan reposetup (ui, repo) yang dipanggil untuk semua ekstensi), atau menggunakan jenis pendekatan kait, dengan hooks.setup hook.
Tetapi sekali lagi, jika Anda menginginkan jawaban yang lebih bermanfaat, Anda harus mempersempit pertanyaan Anda;)
sumber
Kerangka kerja plugin sederhana Marty Allchin adalah basis yang saya gunakan untuk kebutuhan saya sendiri. Saya benar-benar merekomendasikan untuk melihatnya, saya pikir ini benar-benar awal yang baik jika Anda menginginkan sesuatu yang sederhana dan mudah diretas. Anda dapat menemukannya juga sebagai Potongan Django .
sumber
Saya seorang pensiunan ahli biologi yang berurusan dengan micrograqphs digital dan mendapati dirinya harus menulis paket pemrosesan dan analisis gambar (bukan secara teknis perpustakaan) untuk dijalankan pada mesin SGi. Saya menulis kode dalam C dan menggunakan Tcl untuk bahasa scripting. GUI, seperti itu, dilakukan dengan menggunakan Tk. Perintah-perintah yang muncul di Tcl adalah dalam bentuk "extensionName commandName arg0 arg1 ... param0 param1 ...", yaitu, kata-kata dan angka yang dipisahkan dengan spasi sederhana. Ketika Tcl melihat substring "extensionName", kontrol dilewatkan ke paket C. Itu pada gilirannya menjalankan perintah melalui lexer / parser (dilakukan pada lex / yacc) dan kemudian memanggil rutinitas C seperlunya.
Perintah untuk mengoperasikan paket dapat dijalankan satu per satu melalui jendela di GUI, tetapi pekerjaan batch dilakukan dengan mengedit file teks yang merupakan skrip Tcl yang valid; Anda akan memilih templat yang melakukan jenis operasi tingkat file yang ingin Anda lakukan dan kemudian mengedit salinan untuk berisi direktori aktual dan nama file plus perintah paket. Itu bekerja seperti pesona. Sampai ...
1) Dunia beralih ke PC dan 2) skrip mendapatkan lebih dari 500 baris, ketika kemampuan organisasi Tcl yang rapuh mulai menjadi ketidaknyamanan yang nyata. Waktu berlalu ...
Saya pensiun, Python ditemukan, dan itu tampak seperti penerus sempurna Tcl. Sekarang, saya belum pernah melakukan port, karena saya tidak pernah menghadapi tantangan mengkompilasi (cukup besar) program C pada PC, memperluas Python dengan paket C, dan melakukan GUI dengan Python / Gt? / Tk? /? ? Namun, gagasan lama untuk memiliki skrip templat yang dapat diedit tampaknya masih dapat diterapkan. Juga, seharusnya tidak terlalu berat untuk memasukkan perintah paket dalam bentuk Python asli, misalnya:
packageName.command (arg0, arg1, ..., param0, param1, ...)
Beberapa titik, paren, dan koma tambahan, tetapi itu bukan penghalang.
Saya ingat melihat seseorang telah melakukan versi lex dan yacc dengan Python (coba: http://www.dabeaz.com/ply/ ), jadi jika itu masih diperlukan, mereka ada di sekitar.
Maksud dari ocehan ini adalah bahwa bagi saya tampaknya Python sendiri adalah ujung depan "ringan" yang diinginkan yang dapat digunakan oleh para ilmuwan. Saya ingin tahu mengapa Anda berpikir itu tidak benar, dan maksud saya serius.
ditambahkan kemudian: Aplikasi gedit mengantisipasi plugin yang ditambahkan dan situs mereka memiliki penjelasan paling jelas tentang prosedur plugin sederhana yang saya temukan dalam beberapa menit mencari-cari. Mencoba:
https://wiki.gnome.org/Apps/Gedit/PythonPluginHowToOld
Saya masih ingin memahami pertanyaan Anda dengan lebih baik. Saya tidak jelas apakah Anda 1) ingin para ilmuwan dapat menggunakan aplikasi (Python) Anda cukup sederhana dalam berbagai cara atau 2) ingin memungkinkan para ilmuwan untuk menambahkan kemampuan baru ke aplikasi Anda. Pilihan # 1 adalah situasi yang kita hadapi dengan gambar dan yang menyebabkan kita menggunakan skrip generik yang kita modifikasi agar sesuai dengan kebutuhan saat ini. Apakah itu Pilihan # 2 yang mengarahkan Anda ke gagasan plugin, atau apakah itu beberapa aspek dari aplikasi Anda yang membuat mengeluarkan perintah padanya menjadi tidak praktis?
sumber
Ketika saya mencari Python Decorators, menemukan potongan kode yang sederhana namun bermanfaat. Ini mungkin tidak sesuai dengan kebutuhan Anda tetapi sangat menginspirasi.
Sistem Pendaftaran Plugin Scipy Advanced Python #
Pemakaian:
sumber
WordProcessor.plugin
tidak mengembalikan apa pun (None
), jadi mengimporCleanMdashesExtension
kelas nanti hanya mengimporNone
. Jika kelas plugin berguna sendiri, buat.plugin
metode kelasreturn plugin
.Saya menikmati diskusi yang bagus tentang arsitektur plugin yang berbeda yang diberikan oleh Dr Andre Roberge di Pycon 2009. Dia memberikan tinjauan yang baik tentang berbagai cara menerapkan plugin, mulai dari sesuatu yang sangat sederhana.
Ini tersedia sebagai podcast (bagian kedua setelah penjelasan tentang tambalan monyet) disertai dengan serangkaian enam entri blog .
Saya sarankan untuk mendengarkannya dengan cepat sebelum Anda membuat keputusan.
sumber
Saya tiba di sini mencari arsitektur plugin minimal, dan menemukan banyak hal yang semuanya tampak seperti terlalu banyak bagi saya. Jadi, saya sudah menerapkan Plugin Python Super Sederhana . Untuk menggunakannya, Anda membuat satu atau lebih direktori dan meletakkan
__init__.py
file khusus di masing-masing. Mengimpor direktori tersebut akan menyebabkan semua file Python lainnya dimuat sebagai submodules, dan nama mereka akan ditempatkan dalam__all__
daftar. Maka terserah Anda untuk memvalidasi / menginisialisasi / mendaftarkan modul-modul tersebut. Ada contoh di file README.sumber
Sebenarnya setuptools bekerja dengan "direktori plugins", seperti contoh berikut yang diambil dari dokumentasi proyek: http://peak.telecommunity.com/DevCenter/PkgResources#locating-plugins
Contoh penggunaan:
Dalam jangka panjang, setuptools adalah pilihan yang jauh lebih aman karena dapat memuat plugin tanpa konflik atau persyaratan yang hilang.
Manfaat lain adalah bahwa plugin itu sendiri dapat diperpanjang menggunakan mekanisme yang sama, tanpa aplikasi asli harus peduli.
sumber
Sebagai satu sama lain pendekatan untuk sistem plugin, Anda dapat memeriksa proyek Extend Me .
Sebagai contoh, mari kita mendefinisikan kelas sederhana dan ekstensinya
Dan cobalah untuk menggunakannya:
Dan tunjukkan apa yang tersembunyi di balik layar:
ext_me library memanipulasi proses pembuatan kelas melalui metaclasses, jadi dalam contoh di atas, ketika membuat instance baru
MyCoolClass
kita mendapat instance kelas baru yang merupakan subkelas keduanyaMyCoolClassExtension
danMyCoolClass
memiliki fungsionalitas keduanya, berkat pewarisan berganda PythonUntuk kontrol yang lebih baik atas pembuatan kelas ada beberapa metaclasses didefinisikan dalam lib ini:
ExtensibleType
- memungkinkan ekstensibilitas sederhana dengan subclassingExtensibleByHashType
- Mirip dengan ExtensibleType, tetapi memiliki kemampuan untuk membangun versi kelas khusus, memungkinkan ekstensi global kelas dasar dan ekstensi versi kelas khususLib ini digunakan dalam Proyek Proxy OpenERP , dan tampaknya berfungsi cukup baik!
Untuk contoh nyata penggunaan, lihat di ekstensi OpenERP Proxy 'field_datetime' :
Record
di sini adalah objek yang dapat diperpanjang.RecordDateTime
adalah ekstensi.Untuk mengaktifkan ekstensi, cukup impor modul yang berisi kelas ekstensi, dan (dalam hal di atas) semua
Record
objek yang dibuat setelah itu akan memiliki kelas ekstensi di kelas dasar, sehingga memiliki semua fungsinya.Keuntungan utama dari pustaka ini adalah bahwa, kode yang mengoperasikan objek yang dapat diperluas, tidak perlu tahu tentang ekstensi dan ekstensi dapat mengubah segalanya dalam objek yang dapat diperluas.
sumber
my_cool_obj = MyCoolClassExtension1()
bukannyamy_cool_obj = MyCoolClass()
__new__
metode yang diganti , sehingga secara otomatis dapat menemukan semua subclass, dan membangun kelas baru, yaitu subclass dari semuanya, dan mengembalikan instance baru dari kelas yang dibuat ini. Dengan demikian, aplikasi asli tidak perlu tahu tentang semua ekstensi. pendekatan ini berguna ketika membangun perpustakaan, untuk memungkinkan pengguna akhir untuk mengubah atau memperluas bechavior dengan mudah. dalam contoh di atas, MyCoolClass dapat didefinisikan di perpustakaan, dan digunakan olehnya, dan MyCoolClassExtension dapat didefinisikan oleh pengguna akhir.setuptools memiliki EntryPoint :
AFAIK paket ini selalu tersedia jika Anda menggunakan pip atau virtualenv.
sumber
Memperluas jawaban @ edomaur mungkin saya sarankan melihat simple_plugins (plug shameless), yang merupakan kerangka kerja plugin sederhana yang terinspirasi oleh karya Marty Alchin .
Contoh penggunaan singkat berdasarkan README proyek:
sumber
Saya telah menghabiskan waktu membaca utas ini ketika saya sedang mencari kerangka kerja plugin di Python sekarang dan kemudian. Saya telah menggunakan beberapa tetapi ada kekurangan dengan mereka. Inilah yang saya temukan untuk pengamatan Anda pada tahun 2017, antarmuka gratis, sistem manajemen plugin yang digabungkan secara longgar: Muat saya nanti . Berikut ini tutorial tentang cara menggunakannya.
sumber
Anda dapat menggunakan pluginlib .
Plugin mudah dibuat dan dapat dimuat dari paket lain, jalur file, atau titik masuk.
Buat kelas induk plugin, yang mendefinisikan metode apa pun yang diperlukan:
Buat plugin dengan mewarisi kelas induk:
Muat plugin:
sumber
foo
, Anda mungkin memiliki modul bernamafoo.parents
tempat Anda mendefinisikan kelas induk. Maka plugin Anda, akan imporfoo.parents
. Itu bekerja dengan baik untuk sebagian besar kasus penggunaan. Karena 'foo' sendiri juga diimpor, untuk menghindari kemungkinan impor melingkar, banyak proyek membiarkan akar modul kosong dan menggunakan__main__.py
file atau titik masuk untuk meluncurkan aplikasi.Saya telah menghabiskan banyak waktu mencoba menemukan sistem plugin kecil untuk Python, yang sesuai dengan kebutuhan saya. Tapi kemudian saya hanya berpikir, jika sudah ada warisan, yang alami dan fleksibel, mengapa tidak menggunakannya.
Satu-satunya masalah dengan menggunakan warisan untuk plugin adalah Anda tidak tahu apa yang paling spesifik (terendah pada pohon warisan) kelas plugin.
Tapi ini bisa diselesaikan dengan metaclass, yang melacak pewarisan kelas dasar, dan mungkin bisa membangun kelas, yang mewarisi dari plugin yang paling spesifik ('Root extended' pada gambar di bawah)
Jadi saya datang dengan solusi dengan mengkodekan metaclass seperti itu:
Jadi ketika Anda memiliki basis Root, dibuat dengan metaclass, dan memiliki pohon plugin yang mewarisi darinya, Anda bisa secara otomatis mendapatkan kelas, yang mewarisi dari plugin yang paling spesifik hanya dengan subklasifikasi:
Basis kode cukup kecil (~ 30 baris kode murni) dan sefleksibel yang dimungkinkan oleh warisan.
Jika Anda tertarik, libatkan @ https://github.com/thodnev/pluginlib
sumber
Anda juga dapat melihat Groundwork .
Idenya adalah untuk membangun aplikasi di sekitar komponen yang dapat digunakan kembali, yang disebut pola dan plugin. Plugin adalah kelas yang berasal
GwBasePattern
. Inilah contoh dasar:Ada juga pola yang lebih maju untuk menangani misalnya antarmuka baris perintah, pensinyalan atau objek bersama.
Groundwork menemukan plugin-nya baik dengan mengikatnya secara terprogram ke aplikasi seperti yang ditunjukkan di atas atau secara otomatis via
setuptools
. Paket python yang berisi plugin harus mendeklarasikannya menggunakan titik masuk khususgroundwork.plugin
.Ini dokumennya .
Penafian : Saya salah satu penulis Groundwork.
sumber
Dalam produk perawatan kesehatan kami saat ini, kami memiliki arsitektur plugin yang diimplementasikan dengan kelas antarmuka. Tumpukan teknologi kami adalah Django di atas Python untuk API dan Nuxtjs di atas nodejs untuk frontend.
Kami memiliki aplikasi manajer plugin yang ditulis untuk produk kami yang pada dasarnya adalah paket pip dan npm yang sesuai dengan Django dan Nuxtjs.
Untuk pengembangan plugin baru (pip dan npm) kami menjadikan pengelola plugin sebagai dependensi.
Dalam paket Pip: Dengan bantuan setup.py Anda dapat menambahkan titik masuk plugin untuk melakukan sesuatu dengan manajer plugin (registri, inisiasi, ... dll.) Https://setuptools.readthedocs.io/en/latest/setuptools .html # pembuatan skrip otomatis
Dalam paket npm: Mirip dengan pip ada kait dalam skrip npm untuk menangani instalasi. https://docs.npmjs.com/misc/scripts
Penggunaan kami:
Tim pengembangan plugin terpisah dari tim pengembang inti sekarang. Ruang lingkup pengembangan plugin adalah untuk berintegrasi dengan aplikasi pihak ke-3 yang didefinisikan dalam kategori produk apa pun. Antarmuka plugin dikategorikan untuk misalnya: - Faks, telepon, email ... dll. Plugin manager dapat ditingkatkan ke kategori baru.
Dalam kasus Anda: Mungkin Anda dapat memiliki satu plugin yang ditulis dan menggunakan kembali yang sama untuk melakukan hal-hal.
Jika pengembang plugin harus menggunakan kembali objek inti, objek tersebut dapat digunakan dengan melakukan tingkat abstraksi di dalam pengelola plugin agar plugin apa pun dapat mewarisi metode-metode tersebut.
Berbagi saja bagaimana kami menerapkan produk kami berharap itu akan memberikan sedikit ide.
sumber