আমি বোঝার চেষ্টা করছি, বানর প্যাচিং বা বানরের প্যাচ কী?
এটি কি পদ্ধতি / অপারেটরদের ওভারলোডিং বা অর্পণ করার মতো কিছু?
এই জিনিসগুলির সাথে এর কি সাধারণ কিছু আছে?
আমি বোঝার চেষ্টা করছি, বানর প্যাচিং বা বানরের প্যাচ কী?
এটি কি পদ্ধতি / অপারেটরদের ওভারলোডিং বা অর্পণ করার মতো কিছু?
এই জিনিসগুলির সাথে এর কি সাধারণ কিছু আছে?
উত্তর:
না, এটি things জিনিসের মতো নয়। এটি রানটাইমের সময় বৈশিষ্ট্যের গতিশীল প্রতিস্থাপন।
উদাহরণস্বরূপ, একটি ক্লাসের একটি পদ্ধতি রয়েছে তা বিবেচনা করুন get_data
। এই পদ্ধতিটি একটি বাহ্যিক অনুসন্ধান করে (উদাহরণস্বরূপ একটি ডেটাবেস বা ওয়েব এপিআই) এবং ক্লাসের বিভিন্ন পদ্ধতি এটি কল করে। যাইহোক, ইউনিট পরীক্ষায় আপনি বাহ্যিক ডেটা উত্সের উপর নির্ভর করতে চান না - সুতরাং আপনি গতিশীলভাবে get_data
কোনও স্টাবের সাহায্যে পদ্ধতিটি প্রতিস্থাপন করেন যা কিছু স্থির ডেটা দেয়।
পাইথন ক্লাসগুলি পারস্পরিক পরিবর্তনযোগ্য এবং পদ্ধতিগুলি কেবল শ্রেণীর বৈশিষ্ট্য, আপনি নিজের পছন্দ মতো এটি করতে পারেন - এবং বাস্তবে আপনি এমনকি মডিউলে ক্লাস এবং ফাংশনগুলি ঠিক একইভাবে প্রতিস্থাপন করতে পারেন।
তবে, একজন মন্তব্যকারী হিসাবে উল্লেখ করা হয়েছে, বানকিপ্যাচ করার সময় সাবধানতা অবলম্বন করুন:
যদি আপনার পরীক্ষার যুক্তি ছাড়াও অন্য কিছু কল করে get_data
, এটি আপনার বানরের প্যাচ প্রতিস্থাপনের পরিবর্তে আসলটির পরিবর্তে কল করবে - যা ভাল বা খারাপ হতে পারে। শুধু সাবধান।
যদি কিছু পরিবর্তনশীল বা বৈশিষ্ট্য উপস্থিত থাকে যা get_data
আপনি এটি প্রতিস্থাপনের সময় দ্বারা ফাংশনটির দিকেও নির্দেশ করে, এই উপনামটির অর্থ পরিবর্তন হবে না এবং মূলটির দিকে ইঙ্গিত করতে থাকবে get_data
। (কেন? পাইথন কেবল get_data
আপনার ক্লাসে নামটি অন্য কোনও ফাংশন অবজেক্টে পুনর্নির্মাণ করে ; অন্য নামের বাইন্ডিংগুলিতে কোনও প্রভাব পড়ে না))
get_data
, আপনি নামটিকে get_data
একটি মক ফাংশনে পুনরায় ফিরিয়ে দিন । প্রোগ্রামের অন্য কোথাও অন্য নামটি যদি ফাংশন-পূর্ব-পরিচিত-হিসাবে আবদ্ধ থাকে তবে get_data
অন্য নামের জন্য কিছুই পরিবর্তন হবে না।
মনকিপ্যাচটি পাইথন কোডের একটি অংশ যা রানটাইম (সাধারণত শুরুতে সাধারণত) অন্যান্য কোডকে প্রসারিত বা সংশোধন করে।
একটি সাধারণ উদাহরণ এরকম দেখাচ্ছে:
from SomeOtherProduct.SomeModule import SomeClass
def speak(self):
return "ook ook eee eee eee!"
SomeClass.speak = speak
সূত্র: জোপ উইকিতে MonkeyPatch পৃষ্ঠা।
একটি বানর প্যাচ কি?
সহজ কথায় বলতে গেলে, প্রোগ্রামটি চলাকালীন বানর প্যাচিং মডিউল বা শ্রেণিতে পরিবর্তন আনছে।
পান্ডাদের ডকুমেন্টেশনে বানর-প্যাচিংয়ের একটি উদাহরণ রয়েছে:
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
এরপরে আমরা একটি পদ্ধতির সংজ্ঞা তৈরি করি, যা কোনও শ্রেণিবদ্ধ সংজ্ঞাগুলির আওতার বাইরে আনবাউন্ড এবং মুক্ত থাকে (যেহেতু পার্থক্যটি একটি ফাংশন এবং আনবাউন্ড পদ্ধতির মধ্যে মোটামুটি অর্থহীন, তাই পাইথন 3 আনবাউন্ড পদ্ধতির সাথে দূরে থাকে):
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 datasource
def get_data(self):
'''monkey patch datasource.Structure with this to simulate error'''
raise datasource.DataRetrievalError
datasource.Structure.get_data = get_data
এবং আমরা যখন এমন আচরণের জন্য এটি পরীক্ষা করি যা কোনও ত্রুটি বাড়াতে এই পদ্ধতির উপর নির্ভর করে, যদি সঠিকভাবে প্রয়োগ করা হয়, আমরা সেই আচরণটি পরীক্ষার ফলাফলগুলিতে পেয়ে যাব।
কেবলমাত্র উপরের Structure
কাজটিই প্রক্রিয়াটির জীবনযাত্রার জন্য পরিবর্তন ঘটাবে, তাই এটি এড়াতে আপনি আপনার ইউনিটসেটে সেটআপ এবং টিয়ারডাউন ব্যবহার করতে চান, যেমন:
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
পারি নি তবে আমি ধারণা করি এটিতে একইভাবে বানর-প্যাচিং ব্যবহার করা হয়েছে))
উইকিপিডিয়া অনুসারে :
পাইথনে, বানর প্যাচ শব্দটি কেবল রানটাইমের সময় কোনও শ্রেণি বা মডিউলটির গতিশীল পরিবর্তনকে বোঝায়, যা তৃতীয় পক্ষের কোডকে ত্রুটিযুক্ত বা বাগের বৈশিষ্ট্য হিসাবে চিহ্নিত করার উদ্দেশ্যে পরিচালিত হয়েছিল যা আপনার ইচ্ছা অনুযায়ী কাজ করে না।
প্রথম: বানর প্যাচিং একটি দুষ্ট হ্যাক (আমার মতে)।
এটি প্রায়শই একটি কাস্টম বাস্তবায়ন সহ মডিউল বা শ্রেণি স্তরের কোনও পদ্ধতি প্রতিস্থাপন করতে ব্যবহৃত হয়।
যখন আপনি আসল কোডটি প্রতিস্থাপন করতে পারবেন না তখন সর্বাধিক সাধারণ ইউজকেস একটি মডিউল বা শ্রেণিতে বাগের জন্য কাজ করার চেষ্টা করে। এই ক্ষেত্রে আপনি আপনার নিজের মডিউল / প্যাকেজের ভিতরে প্রয়োগের মাধ্যমে বানরের প্যাচিংয়ের মাধ্যমে "ভুল" কোডটি প্রতিস্থাপন করবেন।
বানর প্যাচিং কেবল গতিময় ভাষায় করা যেতে পারে, যার মধ্যে পাইথন একটি ভাল উদাহরণ। অবজেক্টের সংজ্ঞা আপডেট করার পরিবর্তে রানটাইমে একটি পদ্ধতি পরিবর্তন করা একটি উদাহরণ; একইভাবে, রানটাইমটিতে অ্যাট্রিবিউটগুলি (পদ্ধতি বা ভেরিয়েবল যাই হোক না কেন) যুক্ত করা বানর প্যাচিং হিসাবে বিবেচিত হয়। এগুলি প্রায়শই মডিউলগুলির সাথে কাজ করার সময় করা হয় যখন আপনার উত্স নেই, যেমন বস্তুর সংজ্ঞা সহজেই পরিবর্তন করা যায় না।
এটি খারাপ হিসাবে বিবেচিত হয় কারণ এর অর্থ হ'ল কোনও বস্তুর সংজ্ঞাটি আসলে বা তার আচরণের সাথে পুরোপুরি বা সঠিকভাবে বর্ণনা করে না।
বানরের প্যাচিংটি রানটাইমের সময় ক্লাসে বিদ্যমান ক্লাস বা পদ্ধতিগুলি আবার চালু করে এবং আচরণটি পরিবর্তন করছে, যা সতর্কতার সাথে ব্যবহার করা উচিত, বা আপনার যখন সত্যই প্রয়োজন তখন আপনার এটি ব্যবহার করা উচিত।
পাইথন যেহেতু একটি গতিশীল প্রোগ্রামিং ভাষা, শ্রেণিগুলি পারস্পরিক পরিবর্তনযোগ্য তাই আপনি এগুলি আবার খুলতে এবং এগুলি সংশোধন করতে বা এমনকি প্রতিস্থাপন করতে পারেন।
বানর প্যাচিং কি? বানর প্যাচিং একটি কৌশল যা রান-টাইমে কোনও অংশের কোডের আচরণকে গতিশীলভাবে আপডেট করার জন্য ব্যবহৃত হয়।
বানরের প্যাচিং কেন ব্যবহার করবেন? এটি আমাদের উত্স কোডটি সংশোধন না করে রানটাইমের সময় গ্রন্থাগার, মডিউল, শ্রেণি বা পদ্ধতিগুলির আচরণ সংশোধন বা প্রসারিত করতে দেয়
উপসংহার বানর প্যাচিং একটি দুর্দান্ত কৌশল এবং এখন পাইথনে এটি কীভাবে করা যায় তা আমরা শিখেছি। তবে, যেমনটি আমরা আলোচনা করেছি, এর নিজস্ব ত্রুটি রয়েছে এবং সাবধানে ব্যবহার করা উচিত।
আরও তথ্যের জন্য দয়া করে [1] দেখুন: https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with- উদাহরণসমূহ-25eed0aea505
pointing to the original get_data function
? আপনার অর্থ কি যখন আপনি কোনও ভেরিয়েবলের ভিতরে কোনও ফাংশন সঞ্চয় করেন যদি কেউ সেই ফাংশনটি পরিবর্তন করে তবে ভেরিয়েবলটি পুরানোটির দিকে ইশারা করাতে থাকবে?