সামঞ্জস্যের জন্য বস্তুর উদাহরণগুলিকে তাদের গুণাবলী দ্বারা তুলনা করুন


244

আমার একটি ক্লাস MyClassরয়েছে, এতে দুটি সদস্য ভেরিয়েবল রয়েছে fooএবং bar:

class MyClass:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

আমি এই বর্গ, যা প্রত্যেকের জন্য অভিন্ন মান আছে দুই স্থানেই আছে fooএবং bar:

x = MyClass('foo', 'bar')
y = MyClass('foo', 'bar')

যাইহোক, আমি যখন তাদের সাম্যের জন্য তুলনা করি, পাইথন ফিরে আসে False:

>>> x == y
False

আমি কীভাবে পাইথনকে এই দুটি বস্তুর সমান বিবেচনা করতে পারি?

উত্তর:


354

আপনার পদ্ধতিটি কার্যকর করা উচিত __eq__:

class MyClass:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

    def __eq__(self, other): 
        if not isinstance(other, MyClass):
            # don't attempt to compare against unrelated types
            return NotImplemented

        return self.foo == other.foo and self.bar == other.bar

এখন এটি ফলাফল:

>>> x == y
True

নোট করুন যে বাস্তবায়নগুলি __eq__স্বয়ংক্রিয়ভাবে আপনার শ্রেণীর নজিরগুলি ছাপিয়ে যায় না, যার অর্থ সেগুলি সেট এবং ডিকটে সংরক্ষণ করা যায় না। যদি আপনি কোনও অপরিবর্তনীয় ধরণের মডেলিং না করেন (উদাহরণস্বরূপ যদি বৈশিষ্ট্যগুলি fooএবং barআপনার অবজেক্টের জীবনকালের মধ্যে মান পরিবর্তন করতে পারে), তবে কেবলমাত্র আপনার দৃষ্টান্তগুলি অপ্রয়োজনীয় হিসাবে ছেড়ে দেওয়ার পরামর্শ দেওয়া হচ্ছে।

আপনি যদি একটি অপরিবর্তনীয় প্রকারের মডেলিং করেন তবে আপনার ডেটামোডেল হুকটিও প্রয়োগ করা উচিত __hash__:

class MyClass:
    ...

    def __hash__(self):
        # necessary for instances to behave sanely in dicts and sets.
        return hash((self.foo, self.bar))

একটি সাধারণ সমাধান, __dict__মানগুলি লুপিং এবং তুলনা করার মত ধারণার মতো , পরামর্শ দেওয়া যায় না - এটি কখনই সত্যিকার অর্থে সাধারণ হতে পারে না কারণ এর মধ্যে __dict__অন্তর্হীন বা অপরিবর্তনীয় ধরনের থাকতে পারে।

নোট: জেনে রাখুন পাইথন 3 এর আগে আপনার __cmp__পরিবর্তে ব্যবহারের প্রয়োজন হতে পারে __eq__। পাইথন 2 ব্যবহারকারীরা প্রয়োগ করতেও পারেন __ne__, যেহেতু অসমতার জন্য একটি বুদ্ধিমান ডিফল্ট আচরণ (অর্থাত্ সমতা ফলাফলকে উল্টানো) পাইথন 2 এ স্বয়ংক্রিয়ভাবে তৈরি হবে না।


2
আমি return NotImplemented(উত্থাপন পরিবর্তে NotImplementedError) ব্যবহার সম্পর্কে কৌতূহল ছিল । : যে বিষয় এখানে আচ্ছাদিত করছে stackoverflow.com/questions/878943/...
init_js

48

আপনি আপনার বস্তুর মধ্যে সমৃদ্ধ তুলনা অপারেটরদের ওভাররাইড করে ।

class MyClass:
 def __lt__(self, other):
      # return comparison
 def __le__(self, other):
      # return comparison
 def __eq__(self, other):
      # return comparison
 def __ne__(self, other):
      # return comparison
 def __gt__(self, other):
      # return comparison
 def __ge__(self, other):
      # return comparison

এটার মত:

    def __eq__(self, other):
        return self._id == other._id

3
মনে রাখবেন যে, পাইথন 2.5 এবং অগ্রে, বর্গ সংজ্ঞায়িত করতে হবে __eq__(), কিন্তু মাত্র এক __lt__(), __le__(), __gt__(), অথবা __ge__()যে ছাড়াও প্রয়োজন হয়। সে থেকে পাইথন অন্যান্য পদ্ধতিগুলি অনুমান করতে পারে। দেখুন functoolsআরও তথ্যের জন্য।
কেবিএ

1
@ কেবা, আমি সত্য মনে করি না। এটি functoolsমডিউলটির জন্য কাজ করতে পারে , তবে মান তুলকগুলির জন্য কাজ করে না : পদ্ধতিটি বাস্তবায়িত MyObj1 != Myobj2হলে কেবল কাজ করবে __ne__()
আরেল

6
ফান্টুলগুলি সম্পর্কে সুনির্দিষ্ট টিপটি @functools.total_orderingআপনার শ্রেণীর সাজসজ্জার ব্যবহার করা উচিত , তারপরে উপরের মতো আপনি ঠিক __eq__এবং অন্য একজনকে সংজ্ঞায়িত করতে পারেন এবং বাকী
অংশটি

7

__eq__আপনার ক্লাসে পদ্ধতিটি প্রয়োগ করুন ; এটার মতো কিছু:

def __eq__(self, other):
    return self.path == other.path and self.title == other.title

সম্পাদনা করুন: আপনি যদি চান যে আপনার অবজেক্টগুলি সমান তুলনা করতে পারে এবং যদি তাদের সমান উদাহরণস্বরূপ অভিধান থাকে:

def __eq__(self, other):
    return self.__dict__ == other.__dict__

সম্ভবত আপনি বোঝাতে self is otherচেয়েছিলেন তারা একই জিনিস কিনা।
এস.লট

2
-1। এটি দুটি অভিধান উদাহরণ হলেও, পাইথন সেগুলি কী / মান দ্বারা স্বয়ংক্রিয়ভাবে তুলনা করবে। এটি জাভা নয় ...
ই-সন্তুষ্ট

প্রথম সমাধান একটি বাড়াতে পারে AttributeError। আপনাকে লাইনটি প্রবেশ করতে হবে if hasattr(other, "path") and hasattr(other, "title"):( পাইথন ডকুমেন্টেশনে এই দুর্দান্ত উদাহরণটির মতো) like
ম্যাগগিরো

5

সংক্ষিপ্তসার হিসাবে:

  1. এটি অজানা <= ২.০ ( ২.১-এ যোগ করা হয়েছে) চালানো বাদে এর __eq__পরিবর্তে বাস্তবায়নের পরামর্শ দেওয়া হচ্ছে__cmp____eq__
  2. বাস্তবায়ন করতে ভুলবেন না __ne__( খুব বিশেষ কিছু এর মতো return not self.__eq__(other)বা return not self == otherবাদে কিছু হওয়া উচিত )
  3. ভুলে যাবেন না যে অপারেটরটি অবশ্যই তুলনা করতে চান তা প্রতিটি কাস্টম শ্রেণিতে প্রয়োগ করা উচিত (নীচের উদাহরণ দেখুন)।
  4. আপনি যদি কোনও বস্তুর সাথে তুলনা করতে চান যা কোনওটিই নয়, আপনার অবশ্যই এটি প্রয়োগ করা উচিত। দোভাষী এটি অনুমান করতে পারবেন না ... (নীচে উদাহরণ দেখুন)

    class B(object):
      def __init__(self):
        self.name = "toto"
      def __eq__(self, other):
        if other is None:
          return False
        return self.name == other.name
    
    class A(object):
      def __init__(self):
        self.toto = "titi"
        self.b_inst = B()
      def __eq__(self, other):
        if other is None:
          return False
        return (self.toto, self.b_inst) == (other.toto, other.b_inst)

2

আপনার নির্দিষ্ট ক্ষেত্রে উপর নির্ভর করে আপনি এটি করতে পারেন:

>>> vars(x) == vars(y)
True

কোনও বস্তুর ক্ষেত্র থেকে পাইথন অভিধান দেখুন


আকর্ষণীয়, যদিও ওয়ারগুলি একটি ডিক ফেরত দেয়, ইউনিটস্টেটের দোষ ডিক্টএকুয়াল কাজ করে না বলে মনে হয়, যদিও ভিজ্যুয়াল পর্যালোচনা দেখায় যে তারা বাস্তবে সমান। আমি ডিক্টসকে স্ট্রিংয়ে রূপান্তর করে এবং সেগুলির সাথে তুলনা করে এটিকে পেয়েছি: স্ব.অ্যাসেটএকুয়াল (টিআরটি (ওয়ার্স (টিবিএল0)), স্ট্রেড (ওয়ার্স (লোকাল_টিবিএল)))
বেন

2

পাইথন ৩.7 (এবং উপরে) এর ডেটাচলাসগুলির সাথে , সাম্যের জন্য অবজেক্টের উদাহরণগুলির তুলনা একটি ইনবিল্ট বৈশিষ্ট্য।

পাইথন ৩.6 এর জন্য ডেটাচলসের জন্য একটি ব্যাকপোর্ট উপলব্ধ।

(Py37) nsc@nsc-vbox:~$ python
Python 3.7.5 (default, Nov  7 2019, 10:50:52) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from dataclasses import dataclass
>>> @dataclass
... class MyClass():
...     foo: str
...     bar: str
... 
>>> x = MyClass(foo="foo", bar="bar")
>>> y = MyClass(foo="foo", bar="bar")
>>> x == y
True

রেমন্ড হেটেঙ্গারের 2018 পাইকন উপস্থাপনা পাইথন ডেটাচ্লাসগুলির সাথে শুরু করার জন্য একটি দুর্দান্ত উপায়।
শরৎচন্দ্র

1

বস্তুর উদাহরণগুলির সাথে তুলনা করার সময়, __cmp__ফাংশনটি বলা হয়।

যদি == অপারেটর ডিফল্টরূপে আপনার জন্য কাজ না করে তবে আপনি সর্বদা __cmp__অবজেক্টটির জন্য ফাংশনটিকে নতুনভাবে সংজ্ঞায়িত করতে পারেন ।

সম্পাদনা:

হিসাবে চিহ্নিত করা হয়েছে, __cmp__ফাংশন 3.0 থেকে অবচিত করা হয়। পরিবর্তে আপনার "সমৃদ্ধ তুলনা" পদ্ধতিগুলি ব্যবহার করা উচিত ।


1
CMP ফাংশন 3.0+ জন্য অসমর্থিত হয়েছে
ক্রিস্টোফার

1

আপনি যদি এমন এক বা একাধিক ক্লাসের সাথে ডিল করছেন যা আপনি ভিতরে থেকে পরিবর্তন করতে পারবেন না , তবে এটি করার সাধারণ এবং সহজ উপায় রয়েছে যা কোনও নির্দিষ্ট-নির্দিষ্ট লাইব্রেরির উপরও নির্ভর করে না:

অত্যন্ত জটিল-অবজেক্টগুলির পক্ষে সবচেয়ে সহজ, অনিরাপদ

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যেকোন আগে আগে পাইথনের অন্তর্নির্মিত পদ্ধতিটি ব্যবহার করতে পারেন ।


0

আমি এটি লিখেছি এবং এটি test/utilsআমার প্রকল্পের একটি মডিউলে রেখেছি। ক্ষেত্রে যখন এটি কোনও শ্রেণি নয়, কেবল অল 'ডিকের পরিকল্পনা করুন, এটি উভয় বস্তুকে অতিক্রম করবে এবং নিশ্চিত করবে

  1. প্রতিটি বৈশিষ্ট্য তার সমমনা সমান
  2. কোনও ঝুঁকির অ্যাট্রিবিউট উপস্থিত নেই (কেবলমাত্র একটি বস্তুর উপরে উপস্থিত থাকা)

এটি বড় ... এটি সেক্সি নয় ... তবে ওহ বোই এটি কাজ করে!

def assertObjectsEqual(obj_a, obj_b):

    def _assert(a, b):
        if a == b:
            return
        raise AssertionError(f'{a} !== {b} inside assertObjectsEqual')

    def _check(a, b):
        if a is None or b is None:
            _assert(a, b)
        for k,v in a.items():
            if isinstance(v, dict):
                assertObjectsEqual(v, b[k])
            else:
                _assert(v, b[k])

    # Asserting both directions is more work
    # but it ensures no dangling values on
    # on either object
    _check(obj_a, obj_b)
    _check(obj_b, obj_a)

আপনি এটিকে কিছুটা সরিয়ে _assertকেবল প্লেইন ওল ব্যবহার করে কিছুটা সাফ করতে পারেন assertতবে তারপরে ব্যর্থ হওয়ার পরে আপনি যে বার্তাটি পান তা খুব অসহ্য।


0

আপনার পদ্ধতিটি কার্যকর করা উচিত __eq__:

 class MyClass:
      def __init__(self, foo, bar, name):
           self.foo = foo
           self.bar = bar
           self.name = name

      def __eq__(self,other):
           if not isinstance(other,MyClass):
                return NotImplemented
           else:
                #string lists of all method names and properties of each of these objects
                prop_names1 = list(self.__dict__)
                prop_names2 = list(other.__dict__)

                n = len(prop_names1) #number of properties
                for i in range(n):
                     if getattr(self,prop_names1[i]) != getattr(other,prop_names2[i]):
                          return False

                return True

2
দয়া করে আপনার উত্তরটি সম্পাদনা করুন এবং এটি আরও দশটি উত্তর থেকে আলাদা কেন তা ব্যাখ্যা করে আপনার কোডে আরও ব্যাখ্যা যুক্ত করুন। এই প্রশ্নটি দশ বছরের পুরনো , ইতিমধ্যে একটি স্বীকৃত উত্তর এবং বেশ কয়েকটি খুব উচ্চ-মানের উত্তর রয়েছে। অতিরিক্ত বিশদ ছাড়াই আপনার উত্তর অন্যের তুলনায় অনেক কম মানের এবং সম্ভবত সম্ভবত নিম্নচূড়িত বা মোছা হবে।
দাস_গীক

0

দুটি বস্তুর স্তরক্রমের মধ্যে গভীর তুলনা করে নীচে (আমার সীমাবদ্ধ পরীক্ষায়) কাজ করা হয়। বিভিন্ন ক্ষেত্রে কেস সহ হ্যান্ডেলগুলি যখন বস্তুগুলি তাদের বা তার বৈশিষ্ট্যগুলি অভিধান হয়।

def deep_comp(o1:Any, o2:Any)->bool:
    # NOTE: dict don't have __dict__
    o1d = getattr(o1, '__dict__', None)
    o2d = getattr(o2, '__dict__', None)

    # if both are objects
    if o1d is not None and o2d is not None:
        # we will compare their dictionaries
        o1, o2 = o1.__dict__, o2.__dict__

    if o1 is not None and o2 is not None:
        # if both are dictionaries, we will compare each key
        if isinstance(o1, dict) and isinstance(o2, dict):
            for k in set().union(o1.keys() ,o2.keys()):
                if k in o1 and k in o2:
                    if not deep_comp(o1[k], o2[k]):
                        return False
                else:
                    return False # some key missing
            return True
    # mismatched object types or both are scalers, or one or both None
    return o1 == o2

এটি একটি খুব জটিল কোড তাই দয়া করে এমন কোনও ক্ষেত্রে যুক্ত করুন যা মন্তব্যগুলিতে আপনার পক্ষে কাজ না করে।


0
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

    def __repr__(self):
        return str(self.value)

    def __eq__(self,other):
        return self.value == other.value

node1 = Node(1)
node2 = Node(1)

print(f'node1 id:{id(node1)}')
print(f'node2 id:{id(node2)}')
print(node1 == node2)
>>> node1 id:4396696848
>>> node2 id:4396698000
>>> True

-1

আপনি যদি কোনও অ্যাট্রিবিউট বাই অ্যাট্রিবিউট তুলনা পেতে চান এবং এটি কোথায় ব্যর্থ হয় তা দেখুন, আপনি নীচের তালিকাটি বোঝার ব্যবহার করতে পারেন:

[i for i,j in 
 zip([getattr(obj_1, attr) for attr in dir(obj_1)],
     [getattr(obj_2, attr) for attr in dir(obj_2)]) 
 if not i==j]

এখানে অতিরিক্ত সুবিধা হ'ল আপনি এটির একটি লাইন চেপে নিন এবং পাইচার্মে ডিবাগ করার সময় "মূল্যায়ন এক্সপ্রেশন" উইন্ডোতে প্রবেশ করতে পারেন।


-3

আমি প্রাথমিক উদাহরণটি চেষ্টা করেছি (উপরে 7 দেখুন) এবং এটি আইপথনে কাজ করে না। নোট করুন যে দুটি অভিন্ন বস্তুর উদাহরণ ব্যবহার করে সিএমপি (obj1, obj2) একটি "1" প্রদান করে। অদ্ভুতভাবে যথেষ্ট যখন আমি একটি বৈশিষ্ট্য মানগুলি সংশোধন করি এবং পুনরায় তুলনা করি, cmp (obj1, obj2) ব্যবহার করে অবজেক্টটি একটি "1" ফিরিয়ে দেয়। (দীর্ঘশ্বাস...)

ঠিক আছে, সুতরাং আপনাকে যা করতে হবে তা হল দুটি বস্তুর পুনরাবৃত্তি এবং == চিহ্ন ব্যবহার করে প্রতিটি বৈশিষ্ট্যের তুলনা করুন।


পাইথন ২.7 এ কমপক্ষে, অবজেক্টগুলি ডিফল্টরূপে পরিচয়ের সাথে তুলনা করা হয়। এর অর্থ সিপিথনের পক্ষে ব্যবহারিক কথায় তারা তাদের মেমরি ঠিকানার সাথে তুলনা করে। এজন্য সিএমপি (ও 1, ও 2) কেবল তখনই ফিরে আসে যখন "o1 o2 হয়" এবং ধারাবাহিকভাবে 1 বা -1 আইডি (o1) এবং আইডি (o2) এর মানের উপর নির্ভর করে
yacc143

-6

== এর সাথে তুলনা করা হলে কোনও শ্রেণীর নজিরটি অ-সমান হয়। সর্বোত্তম উপায় হ'ল আপনার ক্লাসে সিএমপি ফাংশন দেওয়া যা স্টাফটি করবে।

আপনি যদি বিষয়বস্তু দ্বারা তুলনা করতে চান তবে আপনি সহজভাবে সিএমপি ব্যবহার করতে পারেন (1জেক্ট 1, অজেজ 2)

আপনার ক্ষেত্রে সিএমপি (ডক্ট 1, ডক্ট 2) সামগ্রী-বিষয়গুলি একই রকম হলে এটি -1 আসবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.