Saya mencoba memahami, apa itu tambalan monyet atau tambalan monyet?
Apakah itu seperti metode / operator yang kelebihan muatan atau pendelegasian?
Apakah ada kesamaan dengan hal-hal ini?
python
terminology
monkeypatching
Sergei Basharov
sumber
sumber
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.
Jawaban:
Tidak, tidak seperti semua itu. Ini hanyalah penggantian dinamis atribut saat runtime.
Misalnya, pertimbangkan kelas yang memiliki metode
get_data
. Metode ini melakukan pencarian eksternal (pada database atau API web, misalnya), dan berbagai metode lain di kelas menyebutnya. Namun, dalam pengujian unit, Anda tidak ingin bergantung pada sumber data eksternal - jadi Anda secara dinamis menggantiget_data
metode dengan sebuah rintisan yang mengembalikan beberapa data tetap.Karena kelas Python bisa berubah, dan metode hanyalah atribut dari kelas, Anda dapat melakukan ini sebanyak yang Anda suka - dan, pada kenyataannya, Anda bahkan dapat mengganti kelas dan fungsi dalam modul dengan cara yang persis sama.
Tapi, seperti yang ditunjukkan komentator , berhati-hatilah saat melakukan monkeypatching:
Jika ada hal lain selain tes logika panggilan Anda
get_data
juga, itu juga akan memanggil pengganti monyet Anda yang ditambal daripada yang asli - yang bisa baik atau buruk. Waspadalah.Jika ada beberapa variabel atau atribut yang juga menunjuk ke
get_data
fungsi pada saat Anda menggantinya, alias ini tidak akan mengubah artinya dan akan terus menunjuk ke yang asliget_data
. (Kenapa? Python hanya me-rebind namaget_data
di kelas Anda ke beberapa objek fungsi lainnya; binding nama lain tidak terpengaruh sama sekali.)sumber
pointing to the original get_data function
? Maksud Anda saat Anda menyimpan fungsi di dalam variabel jika seseorang mengubah fungsi itu, variabel akan terus menunjuk ke yang lama?get_data
, Anda mengubah namaget_data
menjadi fungsi tiruan. Jika beberapa nama lain di tempat lain dalam program terikat ke-fungsi-sebelumnya-dikenal-sebagai-get_data
, tidak ada yang akan berubah untuk nama lain itu.Contoh sederhana terlihat seperti ini:
Sumber: halaman MonkeyPatch di Zope wiki.
sumber
Sederhananya, patch monyet membuat perubahan pada modul atau kelas saat program sedang berjalan.
Contoh dalam penggunaan
Ada contoh tambalan monyet dalam dokumentasi Pandas:
Untuk memecah ini, pertama kita mengimpor modul kami:
Selanjutnya kita membuat definisi metode, yang ada tidak terikat dan bebas di luar ruang lingkup definisi kelas apa pun (karena perbedaannya cukup berarti antara fungsi dan metode tidak terikat, Python 3 tidak jauh dengan metode tidak terikat):
Selanjutnya kita cukup melampirkan metode itu ke kelas yang ingin kita gunakan:
Dan kemudian kita bisa menggunakan metode ini pada instance kelas, dan menghapus metode ketika kita selesai:
Peringatan untuk nama-mangling
Jika Anda menggunakan susunan-nama (atribut awalan dengan garis bawah-ganda, yang mengubah nama, dan yang tidak saya sarankan), Anda harus memotong-motong nama secara manual jika Anda melakukannya. Karena saya tidak merekomendasikan pembuatan nama, saya tidak akan menunjukkannya di sini.
Contoh Pengujian
Bagaimana kita bisa menggunakan pengetahuan ini, misalnya, dalam pengujian?
Katakanlah kita perlu mensimulasikan panggilan pengambilan data ke sumber data luar yang menghasilkan kesalahan, karena kami ingin memastikan perilaku yang benar dalam kasus seperti itu. Kita dapat menambal monyet struktur data untuk memastikan perilaku ini. (Jadi menggunakan nama metode yang mirip seperti yang disarankan oleh Daniel Roseman :)
Dan ketika kami mengujinya untuk perilaku yang bergantung pada metode ini meningkatkan kesalahan, jika diterapkan dengan benar, kami akan mendapatkan perilaku itu dalam hasil pengujian.
Hanya dengan melakukan hal di atas akan mengubah
Structure
objek selama proses berlangsung, jadi Anda akan ingin menggunakan setup dan teardown di unittests Anda untuk menghindari melakukan itu, misalnya:(Sementara di atas baik-baik saja, mungkin akan menjadi ide yang baik untuk menggunakan
mock
perpustakaan untuk menambal kode.mock
'Spatch
dekorator akan kurang rawan kesalahan daripada melakukan hal di atas, yang akan membutuhkan lebih baris kode dan dengan demikian lebih banyak kesempatan untuk memperkenalkan kesalahan Saya belum meninjau kode dimock
tapi saya membayangkan menggunakan patch-monyet dengan cara yang sama.)sumber
Menurut Wikipedia :
sumber
Pertama: patch monyet adalah hack jahat (menurut saya).
Ini sering digunakan untuk mengganti metode pada tingkat modul atau kelas dengan implementasi kustom.
Penggunaan kata kunci yang paling umum adalah menambahkan solusi untuk bug dalam modul atau kelas ketika Anda tidak dapat mengganti kode asli. Dalam hal ini Anda mengganti kode "salah" melalui tambalan monyet dengan implementasi di dalam modul / paket Anda sendiri.
sumber
Penambalan monyet hanya bisa dilakukan dalam bahasa yang dinamis, yang contohnya adalah python. Mengubah metode saat runtime alih-alih memperbarui definisi objek adalah salah satu contohnya, sama halnya dengan menambahkan atribut (apakah metode atau variabel) pada saat runtime dianggap sebagai patch monyet. Ini sering dilakukan ketika bekerja dengan modul yang tidak memiliki sumbernya, sehingga definisi objek tidak dapat dengan mudah diubah.
Ini dianggap buruk karena itu berarti bahwa definisi objek tidak sepenuhnya atau akurat menggambarkan bagaimana sebenarnya berperilaku.
sumber
Patching monyet membuka kembali kelas yang ada atau metode di kelas saat runtime dan mengubah perilaku, yang harus digunakan dengan hati-hati, atau Anda harus menggunakannya hanya ketika Anda benar-benar perlu.
Karena Python adalah bahasa pemrograman yang dinamis, Kelas bisa berubah sehingga Anda dapat membukanya kembali dan memodifikasi atau bahkan menggantinya.
sumber
Untuk info lebih lanjut Silakan merujuk [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
sumber