Saya pemula python, dan saya baru belajar teknik yang melibatkan kamus dan fungsi. Sintaksnya mudah dan sepertinya hal yang sepele, tetapi indera python saya kesemutan. Sesuatu mengatakan kepada saya bahwa ini adalah konsep yang dalam dan sangat pythonic dan saya tidak begitu memahami pentingnya. Dapatkah seseorang memberi nama pada teknik ini dan menjelaskan bagaimana / mengapa ini berguna?
Tekniknya adalah ketika Anda memiliki kamus python dan fungsi yang ingin Anda gunakan di dalamnya. Anda memasukkan elemen tambahan ke dalam dict, yang nilainya adalah nama fungsi. Ketika Anda siap untuk memanggil fungsi Anda mengeluarkan panggilan secara tidak langsung dengan merujuk pada elemen dict, bukan fungsi dengan nama.
Contoh yang saya kerjakan adalah dari Learn Python the Hard Way, 2nd Ed. (Ini adalah versi yang tersedia ketika Anda mendaftar melalui Udemy.com ; sayangnya versi HTML gratis langsung saat ini Ed 3, dan tidak lagi menyertakan contoh ini).
Mengutip:
# make a dictionary of US states and major cities
cities = {'San Diego':'CA', 'New York':'NY', 'Detroit':'MI'}
# define a function to use on such a dictionary
def find_city (map, city):
# does something, returns some value
if city in map:
return map[city]
else:
return "Not found"
# then add a final dict element that refers to the function
cities['_found'] = find_city
Kemudian ekspresi berikut ini setara. Anda dapat memanggil fungsi secara langsung, atau dengan merujuk elemen dict yang nilainya adalah fungsi.
>>> find_city (cities, 'New York')
NY
>>> cities['_found'](cities, 'New York')
NY
Dapatkah seseorang menjelaskan fitur bahasa apa ini, dan mungkin di mana ia bisa bermain dalam pemrograman "nyata"? Latihan mainan ini sudah cukup untuk mengajari saya sintaks, tetapi tidak membawa saya ke sana.
sumber
Jawaban:
Dengan menggunakan dikt, Anda dapat menerjemahkan kunci menjadi callable. Kuncinya tidak perlu di-hardcode, seperti pada contoh Anda.
Biasanya, ini adalah bentuk pengiriman penelepon, di mana Anda menggunakan nilai variabel untuk terhubung ke suatu fungsi. Katakanlah suatu proses jaringan mengirimkan kode perintah kepada Anda, pemetaan pengiriman memungkinkan Anda menerjemahkan kode perintah dengan mudah ke dalam kode yang dapat dieksekusi:
Perhatikan bahwa fungsi apa yang kita sebut sekarang sepenuhnya bergantung pada apa nilainya
command
. Kuncinya juga tidak harus cocok; bahkan tidak harus berupa string, Anda dapat menggunakan apa pun yang dapat digunakan sebagai kunci, dan cocok dengan aplikasi spesifik Anda.Menggunakan metode pengiriman lebih aman daripada teknik lain, seperti
eval()
, karena membatasi perintah yang diijinkan untuk apa yang Anda tetapkan sebelumnya. Tidak ada penyerang yang akan menyelundupkanls)"; DROP TABLE Students; --
injeksi melewati meja pengiriman, misalnya.sumber
dict
bertindak sebagai operator (manajer perintah, Invoker, dll).@ Martijn Pieters melakukan pekerjaan dengan baik menjelaskan teknik ini, tetapi saya ingin mengklarifikasi sesuatu dari pertanyaan Anda.
Yang penting untuk diketahui adalah bahwa Anda TIDAK menyimpan "nama fungsi" dalam kamus. Anda menyimpan referensi ke fungsi itu sendiri. Anda dapat melihat ini menggunakan
print
fungsi.f
hanyalah variabel yang mereferensikan fungsi yang Anda tetapkan. Menggunakan kamus memungkinkan Anda untuk mengelompokkan hal-hal yang disukai, tetapi tidak ada bedanya dengan menetapkan fungsi ke variabel yang berbeda.Demikian pula, Anda bisa melewatkan fungsi sebagai argumen.
sumber
Perhatikan bahwa kelas Python sebenarnya hanyalah gula sintaksis untuk kamus. Saat kamu melakukan:
ketika Anda menelepon
benar-benar sama dengan:
yang, setelah resolusi nama, sama seperti:
Salah satu teknik yang berguna adalah untuk memetakan input pengguna ke callback. Sebagai contoh:
Ini bisa juga ditulis di kelas:
sintaks callback mana yang lebih baik tergantung pada aplikasi tertentu dan selera programmer. Yang pertama adalah gaya yang lebih fungsional, yang terakhir lebih berorientasi objek. Yang pertama mungkin terasa lebih alami jika Anda perlu memodifikasi entri dalam kamus fungsi secara dinamis (mungkin berdasarkan input pengguna); yang terakhir mungkin terasa lebih alami jika Anda memiliki satu set pemetaan preset berbeda yang dapat dipilih secara dinamis.
sumber
5 * x
ke5x
(maafkan analogi sederhana).Ada 2 teknik yang melompat ke pikiran saya yang mungkin Anda rujuk, tidak ada yang Pythonic karena mereka lebih luas dari satu bahasa.
1. Teknik penyembunyian informasi / enkapsulasi dan kohesi (mereka biasanya berjalan beriringan sehingga saya menyatukannya).
Anda memiliki objek yang memiliki data, dan Anda melampirkan metode (perilaku) yang sangat kohesif dengan data. Jika Anda perlu mengubah fungsinya, perluas fungsionalitasnya atau buat perubahan lain yang tidak perlu diubah oleh penelepon (dengan asumsi tidak ada data tambahan yang perlu diteruskan).
2. Pengiriman tabel
Bukan case klasik, karena hanya ada satu entri dengan fungsi. Namun, tabel pengiriman digunakan untuk mengatur perilaku yang berbeda dengan kunci sedemikian rupa sehingga mereka dapat memandang ke atas dan dipanggil secara dinamis. Saya tidak yakin apakah Anda memikirkan hal ini karena Anda tidak mengacu pada fungsi dengan cara yang dinamis, namun demikian Anda masih mendapatkan ikatan yang efektif (panggilan "tidak langsung").
Pengorbanan
Satu hal yang perlu diperhatikan adalah apa yang Anda lakukan akan bekerja dengan baik dengan ruang nama kunci yang dikenal. Namun, Anda menjalankan risiko tabrakan antara data dan fungsi dengan ruang nama kunci yang tidak diketahui.
sumber
Saya memposting solusi ini yang menurut saya cukup umum dan dapat berguna karena dibuat sederhana dan mudah untuk beradaptasi dengan kasus-kasus tertentu:
kita juga dapat mendefinisikan daftar di mana setiap elemen adalah objek fungsi dan menggunakan
__call__
metode bawaan. Penghargaan untuk semua untuk inspirasi dan kerja sama."Artis hebat adalah penyederhanaan", Henri Frederic Amiel
sumber