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?
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?
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 mengganti get_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 asli get_data
. (Kenapa? Python hanya me-rebind nama get_data
di kelas Anda ke beberapa objek fungsi lainnya; binding nama lain tidak terpengaruh sama sekali.)
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 nama get_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.
MonkeyPatch adalah bagian dari kode Python yang memperluas atau memodifikasi kode lain saat runtime (biasanya saat startup).
Contoh sederhana terlihat seperti ini:
from SomeOtherProduct.SomeModule import SomeClass
def speak(self):
return "ook ook eee eee eee!"
SomeClass.speak = speak
Sumber: halaman MonkeyPatch di Zope wiki.
Apa itu tambalan monyet?
Sederhananya, patch monyet membuat perubahan pada modul atau kelas saat program sedang berjalan.
Ada contoh tambalan monyet dalam dokumentasi Pandas:
import pandas as pd
def just_foo_cols(self):
"""Get a list of column names containing the string 'foo'
"""
return [x for x in self.columns if 'foo' in x]
pd.DataFrame.just_foo_cols = just_foo_cols # monkey-patch the DataFrame class
df = pd.DataFrame([list(range(4))], columns=["A","foo","foozball","bar"])
df.just_foo_cols()
del pd.DataFrame.just_foo_cols # you can also remove the new method
Untuk memecah ini, pertama kita mengimpor modul kami:
import pandas as pd
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):
def just_foo_cols(self):
"""Get a list of column names containing the string 'foo'
"""
return [x for x in self.columns if 'foo' in x]
Selanjutnya kita cukup melampirkan metode itu ke kelas yang ingin kita gunakan:
pd.DataFrame.just_foo_cols = just_foo_cols # monkey-patch the DataFrame class
Dan kemudian kita bisa menggunakan metode ini pada instance kelas, dan menghapus metode ketika kita selesai:
df = pd.DataFrame([list(range(4))], columns=["A","foo","foozball","bar"])
df.just_foo_cols()
del pd.DataFrame.just_foo_cols # you can also remove the new method
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.
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 :)
import datasource
def get_data(self):
'''monkey patch datasource.Structure with this to simulate error'''
raise datasource.DataRetrievalError
datasource.Structure.get_data = get_data
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:
def setUp(self):
# retain a pointer to the actual real method:
self.real_get_data = datasource.Structure.get_data
# monkey patch it:
datasource.Structure.get_data = get_data
def tearDown(self):
# give the real method back to the Structure object:
datasource.Structure.get_data = self.real_get_data
(Sementara di atas baik-baik saja, mungkin akan menjadi ide yang baik untuk menggunakan mock
perpustakaan untuk menambal kode. mock
'S patch
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 di mock
tapi saya membayangkan menggunakan patch-monyet dengan cara yang sama.)
Menurut Wikipedia :
Dalam Python, istilah tambalan monyet hanya merujuk pada modifikasi dinamis dari kelas atau modul saat runtime, dimotivasi oleh maksud untuk menambal kode pihak ketiga yang ada sebagai solusi untuk bug atau fitur yang tidak bertindak sesuai keinginan Anda.
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.
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.
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.
Apa itu tambalan monyet? Monkey patching adalah teknik yang digunakan untuk memperbarui perilaku sepotong kode secara dinamis saat dijalankan.
Mengapa menggunakan monkey patching? Itu memungkinkan kita untuk memodifikasi atau memperluas perilaku perpustakaan, modul, kelas atau metode saat runtime tanpa benar-benar memodifikasi kode sumber
Kesimpulan Penambalan monyet adalah teknik keren dan sekarang kami telah belajar bagaimana melakukannya dengan Python. Namun, seperti yang kita diskusikan, ia memiliki kekurangannya sendiri dan harus digunakan dengan hati-hati.
Untuk info lebih lanjut Silakan merujuk [1]: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
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.