ฉันกำลังพยายามที่จะเข้าใจการปะของลิงหรือแผ่นปะของลิงคืออะไร
นั่นคือวิธีการ / ผู้ประกอบการมากไปหรือการมอบหมาย?
มันมีอะไรที่เหมือนกันกับสิ่งเหล่านี้หรือไม่?
ฉันกำลังพยายามที่จะเข้าใจการปะของลิงหรือแผ่นปะของลิงคืออะไร
นั่นคือวิธีการ / ผู้ประกอบการมากไปหรือการมอบหมาย?
มันมีอะไรที่เหมือนกันกับสิ่งเหล่านี้หรือไม่?
คำตอบ:
ไม่มันไม่เหมือนสิ่งเหล่านี้เลย มันเป็นเพียงการเปลี่ยนคุณสมบัติแบบไดนามิกที่รันไทม์
get_data
เช่นพิจารณาระดับที่มีวิธีการที่ วิธีนี้ทำการค้นหาภายนอก (บนฐานข้อมูลหรือเว็บ API เป็นต้น) และวิธีการอื่น ๆ ในชั้นเรียนเรียกมันว่า อย่างไรก็ตามในการทดสอบหน่วยคุณไม่ต้องการพึ่งพาแหล่งข้อมูลภายนอก - ดังนั้นคุณจะแทนที่get_data
เมธอดด้วยไดนามิกที่ส่งคืนข้อมูลคงที่บางส่วน
เนื่องจากคลาส Python นั้นไม่แน่นอนและเมธอดเป็นเพียงคุณลักษณะของคลาสคุณจึงสามารถทำสิ่งนี้ได้มากเท่าที่คุณต้องการ - และในความเป็นจริงคุณสามารถแทนที่คลาสและฟังก์ชั่นในโมดูลได้ในลักษณะเดียวกัน
แต่ในฐานะที่เป็นผู้แสดงความคิดเห็นชี้ให้ใช้ความระมัดระวังเมื่อ monkeypatching:
หากมีสิ่งอื่นนอกเหนือจากตรรกะการทดสอบของคุณเรียกget_data
เช่นกันมันก็จะเรียกการแทนที่ลิงที่คุณได้ทำการแก้ไขมากกว่าเดิมซึ่งอาจดีหรือไม่ดีก็ได้ แค่ระวัง
ถ้าตัวแปรบางส่วนหรือแอตทริบิวต์อยู่ที่จุดกับฟังก์ชั่นตามเวลาที่คุณเปลี่ยนสมญานามนี้จะไม่เปลี่ยนความหมายของมันและจะยังคงชี้ไปที่เดิมget_data
get_data
(เพราะอะไร Python เพียงแค่ rebinds ชื่อget_data
ในคลาสของคุณไปยังวัตถุฟังก์ชั่นอื่น ๆ การผูกชื่ออื่น ๆ จะไม่ได้รับผลกระทบเลย)
pointing to the original get_data function
อะไร? คุณหมายถึงเมื่อคุณเก็บฟังก์ชันไว้ในตัวแปรหรือไม่ถ้ามีคนเปลี่ยนฟังก์ชั่นนั้นตัวแปรจะยังคงชี้ไปที่ฟังก์ชันเก่า
get_data
คุณจะใส่ชื่อใหม่get_data
ไปยังฟังก์ชันจำลอง หากชื่ออื่นอยู่ที่อื่นในโปรแกรมจะถูกผูกไว้กับ the-function-before-known-as- get_data
จะไม่มีอะไรเปลี่ยนแปลงสำหรับชื่ออื่น
MonkeyPatch เป็นส่วนหนึ่งของรหัส Python ซึ่งขยายหรือแก้ไขรหัสอื่น ๆ ที่รันไทม์ (โดยทั่วไปเมื่อเริ่มต้น)
ตัวอย่างง่ายๆมีลักษณะเช่นนี้:
from SomeOtherProduct.SomeModule import SomeClass
def speak(self):
return "ook ook eee eee eee!"
SomeClass.speak = speak
ที่มา: หน้าMonkeyPatchบน Zope wiki
แพทช์ลิงคืออะไร?
พูดง่ายๆคือการปะแก้ลิงกำลังทำการเปลี่ยนแปลงโมดูลหรือคลาสในขณะที่โปรแกรมกำลังทำงานอยู่
มีตัวอย่างของการปะแก้ลิงในเอกสาร 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
ในการแยกแยะสิ่งนี้ก่อนอื่นเรานำเข้าโมดูลของเรา:
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
หากคุณกำลังใช้ชื่อ -mangling (คุณลักษณะการเติมคำนำหน้าด้วยเครื่องหมายขีดล่างคู่ซึ่งเปลี่ยนชื่อและที่ฉันไม่แนะนำ) คุณจะต้องใช้ชื่อ -mangle ด้วยตนเองหากคุณทำเช่นนี้ เนื่องจากฉันไม่แนะนำชื่อที่เป็นอันตรายฉันจะไม่แสดงที่นี่
เราจะใช้ความรู้นี้ในการทดสอบได้อย่างไร
สมมติว่าเราต้องการจำลองการเรียกค้นข้อมูลไปยังแหล่งข้อมูลภายนอกที่ทำให้เกิดข้อผิดพลาดเนื่องจากเราต้องการให้แน่ใจว่าพฤติกรรมที่ถูกต้องในกรณีเช่นนี้ เราสามารถแก้ไขโครงสร้างข้อมูลเพื่อให้แน่ใจว่าพฤติกรรมนี้ลิง (ดังนั้นใช้ชื่อวิธีการที่คล้ายกันตามที่แนะนำโดย 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
และเมื่อเราทดสอบหาพฤติกรรมที่อาศัยวิธีนี้ทำให้เกิดข้อผิดพลาดหากนำไปใช้อย่างถูกต้องเราจะได้รับพฤติกรรมนั้นในผลการทดสอบ
เพียงทำตามข้างต้นจะเปลี่ยนStructure
วัตถุสำหรับชีวิตของกระบวนการดังนั้นคุณจะต้องใช้การตั้งค่าและการฉีกขาดใน unittests ของคุณเพื่อหลีกเลี่ยงการทำเช่น:
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
มันอาจจะเป็นความคิดที่ดีกว่าที่จะใช้mock
ห้องสมุดเพื่อแก้ไขรหัสมัณฑนากรmock
ของมันpatch
จะมีข้อผิดพลาดน้อยกว่าการทำตามข้างต้นซึ่งจะต้องใช้รหัสเพิ่มเติมและโอกาสในการแนะนำข้อผิดพลาดมากขึ้น ฉันยังไม่ได้ตรวจสอบรหัสในmock
แต่ฉันคิดว่ามันใช้การปะลิงในลักษณะที่คล้ายกัน)
ตามที่Wikipedia :
ใน Python คำว่า monkey patch อ้างถึงการปรับเปลี่ยนแบบไดนามิกของคลาสหรือโมดูล ณ รันไทม์ซึ่งได้รับแรงบันดาลใจจากเจตนาที่จะแก้ไขโค้ดของบุคคลที่สามที่มีอยู่เพื่อแก้ไขข้อบกพร่องหรือคุณสมบัติที่ไม่ได้ทำตามที่คุณต้องการ
อย่างแรก: การปะลิงคือการแฮ็คที่ชั่วร้าย
มันมักจะใช้เพื่อแทนที่วิธีการในโมดูลหรือระดับชั้นด้วยการใช้งานที่กำหนดเอง
usecase ที่พบบ่อยที่สุดคือการเพิ่มวิธีแก้ปัญหาสำหรับข้อบกพร่องในโมดูลหรือคลาสเมื่อคุณไม่สามารถแทนที่รหัสเดิม ในกรณีนี้คุณแทนที่รหัส "ผิด" ผ่านการปะแก้ลิงด้วยการใช้งานภายในโมดูล / แพ็คเกจของคุณเอง
การปะของลิงสามารถทำได้ในภาษาไดนามิกเท่านั้นซึ่งไพ ธ อนเป็นตัวอย่างที่ดี การเปลี่ยนเมธอดที่รันไทม์แทนการอัพเดตนิยามอ็อบเจ็กต์เป็นหนึ่งในตัวอย่างเช่นเดียวกันการเพิ่มแอ็ตทริบิวต์ (ไม่ว่าเมธอดหรือตัวแปร) ที่รันไทม์จะถูกพิจารณาเป็น patch patch สิ่งเหล่านี้มักเกิดขึ้นเมื่อทำงานกับโมดูลที่คุณไม่มีแหล่งที่มาเช่นคำจำกัดความของวัตถุที่ไม่สามารถเปลี่ยนแปลงได้ง่าย
สิ่งนี้ถือว่าไม่ดีเพราะมันหมายความว่าคำจำกัดความของวัตถุไม่ได้อธิบายอย่างสมบูรณ์หรืออย่างถูกต้องว่ามันทำงานอย่างไร
การปะของลิงกำลังเปิดคลาสหรือวิธีการที่มีอยู่ในคลาสอีกครั้งในขณะรันไทม์และเปลี่ยนพฤติกรรมซึ่งควรใช้ด้วยความระมัดระวังหรือคุณควรใช้เฉพาะเมื่อคุณต้องการจริงๆ
เนื่องจาก Python เป็นภาษาการเขียนโปรแกรมแบบไดนามิกคลาสจึงไม่แน่นอนดังนั้นคุณสามารถเปิดอีกครั้งและแก้ไขหรือแทนที่ได้
การปะของลิงคืออะไร Monkey patching เป็นเทคนิคที่ใช้ในการอัพเดทพฤติกรรมของโค้ดในช่วงรันไทม์
ทำไมต้องใช้การปะของลิง มันช่วยให้เราสามารถปรับเปลี่ยนหรือขยายพฤติกรรมของห้องสมุดโมดูลคลาสหรือวิธีการที่รันไทม์โดยไม่ต้องแก้ไขซอร์สโค้ดจริง
สรุปการปะลิงเป็นเทคนิคที่ยอดเยี่ยมและตอนนี้เราได้เรียนรู้วิธีการทำใน Python อย่างไรก็ตามอย่างที่เราพูดถึงมันมีข้อเสียของตัวเองและควรใช้อย่างระมัดระวัง
สำหรับข้อมูลเพิ่มเติมโปรดอ้างอิง [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.