Jelaskan titik masuk Python?

181

Saya sudah membaca dokumentasi tentang titik masuk telur di Pylons dan di halaman Peak, dan saya masih tidak begitu mengerti. Bisakah seseorang menjelaskannya kepada saya?

Brad Wright
sumber

Jawaban:

168

"Titik masuk" biasanya merupakan fungsi (atau objek seperti fungsi lainnya yang dapat dipanggil) yang mungkin ingin digunakan oleh pengembang atau pengguna paket Python, meskipun objek yang tidak dapat dipanggil dapat diberikan sebagai titik masuk juga (juga dengan benar ditunjukkan dalam komentar!).

Jenis entri yang paling populer adalah titik entri console_scripts , yang menunjuk ke fungsi yang Anda inginkan tersedia sebagai alat baris perintah untuk siapa pun yang menginstal paket Anda. Ini masuk ke setup.py Anda seperti:

entry_points={
    'console_scripts': [
        'cursive = cursive.tools.cmd:cursive_command',
    ],
},

Saya memiliki paket yang baru saja saya gunakan yang disebut "cursive.tools", dan saya ingin membuatnya menyediakan perintah "cursive" yang dapat dijalankan seseorang dari baris perintah, seperti:

$ cursive --help
usage: cursive ...

Cara untuk melakukan ini adalah mendefinisikan suatu fungsi, seperti mungkin fungsi "cursive_command" di cursive / tools / cmd.py yang terlihat seperti:

def cursive_command():
    args = sys.argv[1:]
    if len(args) < 1:
        print "usage: ..."

Dan seterusnya; itu harus mengasumsikan bahwa itu dipanggil dari baris perintah, parsing argumen yang telah diberikan pengguna, dan ... yah, lakukan apa pun perintah yang dirancang untuk dilakukan.

Instal paket docutils untuk contoh penggunaan titik masuk yang bagus: ia akan menginstal sesuatu seperti setengah lusin perintah yang berguna untuk mengubah dokumentasi Python ke format lain.

Brandon Rhodes
sumber
3
dokumen saat setup.pyini tidak mengandung entry_pointssama sekali.
matt wilkie
2
Ini adalah jawaban yang sangat baik karena menunjukkan kekuatan beberapa proyek berbagi nama grup entry_point tunggal, yaitu "console_scripts". Bandingkan jawaban ini dengan jawaban yang lebih umum dari Petri. Anda akan melihat bahwa setuptools harus menggunakan mekanisme pkg_resources ini untuk mendapatkan console_scripts dan kemudian membuat pembungkus shell di sekitar mereka. Menginspirasi? Gunakan ini. Mereka bagus untuk lebih dari sekadar konsol_krips.
Bruno Bronosky
188

EntryPoints menyediakan registrasi nama objek berbasis sistem file yang persisten dan mekanisme impor objek langsung berbasis nama (diimplementasikan oleh paket setuptools ).

Mereka mengaitkan nama objek Python dengan pengenal bentuk bebas. Jadi kode lain yang menggunakan instalasi Python yang sama dan mengetahui pengenal dapat mengakses objek dengan nama yang terkait, di mana pun objek didefinisikan. Nama terkait dapat berupa nama apa saja yang ada dalam modul Python ; misalnya nama kelas, fungsi atau variabel. Mekanisme titik masuk tidak peduli dengan apa namanya, asalkan dapat diimpor.

Sebagai contoh, mari kita gunakan (nama) sebuah fungsi, dan modul python imajiner dengan nama yang sepenuhnya memenuhi syarat 'myns.mypkg.mymodule':

def the_function():
   "function whose name is 'the_function', in 'mymodule' module"
   print "hello from the_function"

Titik masuk didaftarkan melalui deklarasi titik masuk di setup.py. Untuk mendaftarkan fungsi di bawah titik masuk yang disebut 'my_ep_func':

    entry_points = {
        'my_ep_group_id': [
            'my_ep_func = myns.mypkg.mymodule:the_function'
        ]
    },

Seperti yang ditunjukkan contoh, titik masuk dikelompokkan; ada API terkait untuk mencari semua titik masuk milik grup (contoh di bawah).

Setelah instalasi paket (mis. Menjalankan 'python setup.py install'), deklarasi di atas diuraikan oleh setuptools. Itu kemudian menulis informasi yang diuraikan dalam file khusus. Setelah itu, API pkg_resources (bagian dari setuptools) dapat digunakan untuk mencari titik masuk dan mengakses objek dengan nama terkait:

import pkg_resources

named_objects = {}
for ep in pkg_resources.iter_entry_points(group='my_ep_group_id'):
   named_objects.update({ep.name: ep.load()})

Di sini, setuptools membaca informasi titik masuk yang ditulis dalam file khusus. Ia menemukan titik masuk, mengimpor modul (myns.mypkg.mymodule), dan mengambil fungsi yang didefinisikan di sana, saat dipanggil ke pkg_resources.load ().

Dengan anggapan tidak ada pendaftaran titik masuk lain untuk id grup yang sama, memanggil fungsi_kan maka akan menjadi sederhana:

>>> named_objects['my_ep_func']()
hello from the_function

Jadi, walaupun mungkin agak sulit untuk dipahami pada awalnya, mekanisme entry point sebenarnya cukup mudah digunakan. Ini menyediakan alat yang berguna untuk pengembangan perangkat lunak Python pluggable.

Petri
sumber
4
Di mana nama 'my_ep_func' digunakan dalam semua proses ini? Tampaknya tidak digunakan untuk apa pun oleh iterator pkg_resources.
Kamil Kisiel
2
@ KamilKisiel: dalam contoh yang digunakan untuk ilustrasi di sini, nama titik masuknya memang tidak digunakan untuk apa pun, juga tidak perlu; apakah nama titik masuk digunakan untuk apa pun terserah aplikasi. Nama tersedia hanya sebagai atribut nama instance titik entri.
Petri
3
Saya pikir membuang ep.name dan membuat daftar nama_obyek bukan kamus membingungkan jadi saya mengedit jawabannya. Inilah jawaban yang menunjukkan di mana mendapatkan nama dan apakah mengharapkannya menjadi 'fungsi_' atau 'my_ep_func'. Kalau tidak, pembaca harus mencari dokumentasi tambahan di tempat lain. Ini adalah jawaban yang SANGAT BAIK dan merupakan penjelasan terpendek dari entry_point yang pernah saya lihat!
Bruno Bronosky
3
Saya telah membuat proyek di github yang menunjukkan konsep ini. github.com/RichardBronosky/entrypoint_demo
Bruno Bronosky
1
Ini adalah penjelasan yang sangat jelas tentang titik masuk, bahwa Anda untuk penjelasan terperinci. The EntryPointslink basi, meskipun penjelasan sangat jelas.
Rahul Nair
18

Dari sudut pandang abstrak, titik masuk digunakan untuk membuat sistem registri Pyable callable yang mengimplementasikan berbagai antarmuka tertentu. Ada API di pkg_resources untuk melihat titik entri mana yang diiklankan oleh paket yang diberikan serta API untuk menentukan paket mana yang mengiklankan titik masuk tertentu.

Titik masuk berguna untuk memungkinkan satu paket menggunakan plugin yang ada dalam paket lain. Misalnya, proyek Tempel Ian Bicking menggunakan titik masuk secara luas. Dalam hal ini, Anda dapat menulis paket yang mengiklankan pabrik aplikasi WSGI menggunakan titik masuk paste.app_factory.

Penggunaan lain untuk titik masuk adalah enumerasi semua paket pada sistem yang menyediakan beberapa fungsionalitas plugin. Kerangka kerja TurboGears menggunakan python.templating.enginestitik masuk untuk mencari templating library yang diinstal dan tersedia.

Rick Copeland
sumber