আপনি যদি এমন এক বা একাধিক ক্লাসের সাথে ডিল করছেন যা আপনি ভিতরে থেকে পরিবর্তন করতে পারবেন না , তবে এটি করার সাধারণ এবং সহজ উপায় রয়েছে যা কোনও নির্দিষ্ট-নির্দিষ্ট লাইব্রেরির উপরও নির্ভর করে না:
অত্যন্ত জটিল-অবজেক্টগুলির পক্ষে সবচেয়ে সহজ, অনিরাপদ
pickle.dumps(a) == pickle.dumps(b)
pickle
পাইথন অবজেক্টের জন্য একটি সাধারণ সিরিয়ালাইজ লাইব, এবং এইভাবে সত্যিই বেশ কিছু কিছু সিরিয়ালাইজ করতে সক্ষম হবে। উপরের স্নিপেটে আমি str
সিরিয়ালযুক্ত থেকে অন্যটির a
সাথে তুলনা করছি b
। পরবর্তী পদ্ধতির মতো নয়, এটির জন্য কাস্টম ক্লাসগুলি পরীক্ষা করার সুবিধা রয়েছে।
সবচেয়ে বড় ঝামেলা: নির্দিষ্ট অর্ডারিং এবং [ডি / এন] কোডিং পদ্ধতির pickle
কারণে সমান বস্তুগুলির জন্য একই ফল পাওয়া যাবে না , বিশেষত যখন আরও জটিল বিষয়গুলির সাথে আচরণ করা হয় (যেমন নীস্টে কাস্টম-শ্রেণীর উদাহরণগুলির তালিকা) আপনি প্রায়শই খুঁজে পাবেন কিছু তৃতীয় পক্ষের libs মধ্যে। এই ক্ষেত্রে, আমি একটি ভিন্ন পদ্ধতির সুপারিশ করব:
পুরোপুরি, কোনও-অবজেক্ট পদ্ধতিতে নিরাপদ
আপনি একটি পুনরাবৃত্ত প্রতিবিম্ব লিখতে পারেন যা আপনাকে সিরিয়ালাইজযোগ্য অবজেক্ট দেবে এবং তারপরে ফলাফলগুলি তুলনা করবে
from collections.abc import Iterable
BASE_TYPES = [str, int, float, bool, type(None)]
def base_typed(obj):
"""Recursive reflection method to convert any object property into a comparable form.
"""
T = type(obj)
from_numpy = T.__module__ == 'numpy'
if T in BASE_TYPES or callable(obj) or (from_numpy and not isinstance(T, Iterable)):
return obj
if isinstance(obj, Iterable):
base_items = [base_typed(item) for item in obj]
return base_items if from_numpy else T(base_items)
d = obj if T is dict else obj.__dict__
return {k: base_typed(v) for k, v in d.items()}
def deep_equals(*args):
return all(base_typed(args[0]) == base_typed(other) for other in args[1:])
এখন আপনার বিষয়গুলি কী তা বিচার্য নয়, গভীর সাম্যতা কাজ করার আশ্বাস দেয়
>>> from sklearn.ensemble import RandomForestClassifier
>>>
>>> a = RandomForestClassifier(max_depth=2, random_state=42)
>>> b = RandomForestClassifier(max_depth=2, random_state=42)
>>>
>>> deep_equals(a, b)
True
তুলনার সংখ্যাও ততটা গুরুত্বপূর্ণ নয়
>>> c = RandomForestClassifier(max_depth=2, random_state=1000)
>>> deep_equals(a, b, c)
False
এর জন্য আমার ব্যবহারের ক্ষেত্রে বিডিডি পরীক্ষার মধ্যে ইতিমধ্যে প্রশিক্ষিত মেশিন লার্নিং মডেলের বিচিত্র সেটগুলির মধ্যে গভীর সাম্যতা পরীক্ষা করা ছিল। মডেলগুলি তৃতীয় পক্ষের বিভিন্ন ধরণের লিবের অন্তর্ভুক্ত। অবশ্যই __eq__
এখানে অন্যান্য উত্তরের মতো বাস্তবায়ন আমার পক্ষে বিকল্প ছিল না suggest
সমস্ত ঘাঁটি Coverাকা
আপনি একটি দৃশ্যকল্প যেখানে এক বা কাস্টম ক্লাস আরও তুলনা করা হচ্ছে হতে পারে একটি না থাকে __dict__
বাস্তবায়ন । যে কোনো উপায়ে সাধারণ নয়, কিন্তু এটা sklearn এর এলোমেলো বন ক্লাসিফায়ার মধ্যে একটি উপপ্রকার ক্ষেত্রে হল: <type 'sklearn.tree._tree.Tree'>
। ক্ষেত্রে ভিত্তি করে একটি মামলা এই পরিস্থিতিতে আচরণ - যেমন বিশেষভাবে , আমি একটি পদ্ধতি যে আমাকে উদাহরণস্বরূপ উপর প্রতিনিধি তথ্য (এই ক্ষেত্রে, দেয় বিষয়বস্তুর সঙ্গে নিপীড়িত ধরনের বিষয়বস্তু প্রতিস্থাপন করার সিদ্ধান্ত নিয়েছে __getstate__
পদ্ধতি)। যেমন, দ্বিতীয় থেকে শেষ সারিটি base_typed
হয়ে ওঠে
d = obj if T is dict else obj.__dict__ if '__dict__' in dir(obj) else obj.__getstate__()
সম্পাদনা: সংগঠনের অনুরোধে জন্য, আমি শেষ দুই লাইন প্রতিস্থাপন base_typed
সঙ্গে return dict_from(obj)
, এবং আরও অস্পষ্ট লিব মিটমাট করার জন্য একটি সত্যিই জেনেরিক প্রতিফলন বাস্তবায়িত (আমি, আপনি দিকে তাকিয়ে আছি Doc2Vec)
def isproperty(prop, obj):
return not callable(getattr(obj, prop)) and not prop.startswith('_')
def dict_from(obj):
"""Converts dict-like objects into dicts
"""
if isinstance(obj, dict):
# Dict and subtypes are directly converted
d = dict(obj)
elif '__dict__' in dir(obj):
d = obj.__dict__
elif str(type(obj)) == 'sklearn.tree._tree.Tree':
# Replaces sklearn trees with their state metadata
d = obj.__getstate__()
else:
# Extract non-callable, non-private attributes with reflection
kv = [(p, getattr(obj, p)) for p in dir(obj) if isproperty(p, obj)]
d = {k: v for k, v in kv}
return {k: base_typed(v) for k, v in d.items()}
মনে রাখবেন না উপরোক্ত পদ্ধতিগুলির মধ্যে কোনও True
একই কী-মান জোড়ের সাথে ভিন্ন ভিন্ন কী / মান অর্ডার সহ বিভিন্ন অবজেক্টের ফলন দেয়
>>> a = {'foo':[], 'bar':{}}
>>> b = {'bar':{}, 'foo':[]}
>>> pickle.dumps(a) == pickle.dumps(b)
False
তবে আপনি যদি চান যে আপনি sorted
যেকোন আগে আগে পাইথনের অন্তর্নির্মিত পদ্ধতিটি ব্যবহার করতে পারেন ।
return NotImplemented
(উত্থাপন পরিবর্তেNotImplementedError
) ব্যবহার সম্পর্কে কৌতূহল ছিল । : যে বিষয় এখানে আচ্ছাদিত করছে stackoverflow.com/questions/878943/...