পাইথন! = অপারেশন বনাম "নয়"


248

এই প্রশ্নের একটি মন্তব্যে , আমি একটি বিবৃতি দেখেছি যা ব্যবহারের সুপারিশ করেছে

result is not None

বনাম

result != None

আমি ভাবছিলাম যে পার্থক্যটি কী এবং কেন একজনের অপরটির চেয়ে সুপারিশ করা যেতে পারে?



1
হুম। উভয় প্রশ্নের উত্তর একই ধারণা থাকা সত্ত্বেও আমি মনে করি যে এখানে upvotes এবং বিস্তারিত উত্তরগুলি স্বতন্ত্রভাবে পরিচয় এবং সমতা পরীক্ষার ধারণায় অবদান রাখে।
viksit

উত্তর:


301

==একটি সমতা পরীক্ষা । এটি ডান হাতের পাশ এবং বাম হাতের সমান অবজেক্ট (তাদের __eq__বা __cmp__পদ্ধতি অনুসারে ) কিনা তা পরীক্ষা করে )

isএকটি পরিচয় পরীক্ষা । এটি ডান হাতের দিক এবং বাম হাতের দিকটি একই জিনিস কিনা তা পরীক্ষা করে। কোনও মেথকাকলগুলি করা হয় না, বস্তুগুলি isঅপারেশনকে প্রভাবিত করতে পারে না ।

আপনি is(এবং is not) সিঙ্গেলনের জন্য ব্যবহার করেন , যেমন Noneআপনি যেখানে এমন বস্তুগুলির বিষয়ে চিন্তা করেন না যেগুলি যেগুলি ভান Noneকরতে চায় এবং যেখানে আপনি যখন তুলনা করার সময় ভাঙা বস্তুগুলির বিরুদ্ধে সুরক্ষা রাখতে চান None


3
উত্তরের জন্য ধন্যবাদ - কোনও কিছুর সাথে তুলনা করে কোনও পরিস্থিতি ভেঙে যেতে পারে এমন পরিস্থিতিতে আপনি কী বিশদ বর্ণনা করতে পারেন?
viksit

3
@viksit। Noneকয়েকটি পদ্ধতি রয়েছে এবং প্রায় কোনও বৈশিষ্ট্য নেই। যদি আপনার __eq__পরীক্ষাটি কোনও পদ্ধতি বা বৈশিষ্ট্য প্রত্যাশিত হয় তবে এটি ভেঙে যেতে পারে। def __eq__( self, other ): return self.size == other.size। উদাহরণস্বরূপ, যদি otherঘটে যায় তবে ভাঙ্গবে None
এস .লট

36
এটি বোঝার জন্য আমার প্রিয় উপায়: পাইথনটি isজাভা-র মতো ==। পাইথন জাওয়ার ==মতো .equals()। অবশ্যই আপনি যদি জাভা জানেন তবে এটি সহায়তা করে।
ম্যাট্রিক্সফ্রোগ

4
@ ম্যাট্রিক্সফ্রোগ: পিএইচপি বা জাভাস্ক্রিপ্টে আমরা বলব যে isএটি ===(খুব সমান), এবং বিপরীতভাবে is notএর মতো !==(ঠিক সমান নয়)।
অরওলোফিল

3
কি is notএকটি একক অপারেটর বা এটা শুধু ফল অস্বীকার করা হয় isমত অভ্যন্তরীণভাবে not foo is bar?
আসাদ মূসভী

150

প্রথমে আমাকে কয়েক শর্তে যেতে দিন। আপনি যদি কেবল আপনার প্রশ্নের উত্তর চান তা চাইলে "আপনার প্রশ্নের উত্তর দেওয়ার জন্য" স্ক্রোল করুন।

সংজ্ঞা

অবজেক্টের পরিচয় : আপনি যখন কোনও অবজেক্ট তৈরি করেন, আপনি এটিকে একটি ভেরিয়েবলের জন্য বরাদ্দ করতে পারেন। এরপরে আপনি এটিকে অন্য ভেরিয়েবলকেও বরাদ্দ করতে পারেন। এবং অন্য.

>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True

এই ক্ষেত্রে, cancel, close, এবং dismissসব একই বস্তু মেমরি পড়ুন। আপনি কেবল একটি Buttonবস্তু তৈরি করেছেন এবং তিনটি ভেরিয়েবল এই একটি অবজেক্টকে উল্লেখ করে। আমরা বলতে cancel, closeএবং dismissসব পড়ুন অভিন্ন বস্তু; যে, তারা একটি একক বস্তু উল্লেখ।

অবজেক্টের সমতা : আপনি যখন দুটি বস্তুর তুলনা করেন, আপনি সাধারণত যত্ন নেন না যে এটি মেমরিতে ঠিক একই বস্তুকে বোঝায় । বস্তুর সাম্যতার সাথে আপনি কীভাবে দুটি বস্তুর তুলনা করতে পারেন তার জন্য নিজের বিধিগুলি সংজ্ঞায়িত করতে পারেন। আপনি যখন লিখবেন if a == b:, আপনি মূলত বলছেন if a.__eq__(b):। এটি আপনাকে এমন একটি __eq__পদ্ধতি নির্ধারণ করতে দেয় aযাতে আপনি নিজের তুলনা যুক্তি ব্যবহার করতে পারেন।

সমতা তুলনার জন্য যুক্তিযুক্ত

যুক্তি: দুটি বস্তুর ঠিক একই ডেটা রয়েছে তবে অভিন্ন নয়। (এগুলি স্মৃতিতে একই জিনিস নয়)) উদাহরণ: স্ট্রিংস

>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True

দ্রষ্টব্য: আমি এখানে ইউনিকোড স্ট্রিং ব্যবহার করি কারণ পাইথন স্মৃতিতে নতুন তৈরি না করে নিয়মিত স্ট্রিংগুলি পুনরায় ব্যবহার করতে যথেষ্ট স্মার্ট।

এখানে আমার দুটি ইউনিকোড স্ট্রিং রয়েছে aএবং b। তাদের ঠিক একই বিষয়বস্তু রয়েছে তবে তারা স্মৃতিতে একই জিনিস নয়। যাইহোক, আমরা যখন তাদের তুলনা করি, আমরা তাদের সমান তুলনা করতে চাই। এখানে যা ঘটছে তা হ'ল ইউনিকোড অবজেক্টটি __eq__পদ্ধতিটি কার্যকর করেছে ।

class unicode(object):
    # ...

    def __eq__(self, other):
        if len(self) != len(other):
            return False

        for i, j in zip(self, other):
            if i != j:
                return False

        return True

দ্রষ্টব্য: __eq__এটি unicodeঅবশ্যই এর চেয়ে আরও কার্যকরভাবে প্রয়োগ করা হয়েছে।

যুক্তি: দুটি বস্তুর আলাদা আলাদা ডেটা থাকে তবে কিছু কী ডেটা একই থাকলে একই জিনিস হিসাবে বিবেচিত হবে। উদাহরণ: বেশিরভাগ ধরণের মডেল ডেটা

>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True

এখানে, আমি দুই ডেল মনিটর আছে, aএবং b। তাদের একই মেক এবং মডেল রয়েছে। তবে মেমরির ক্ষেত্রে তাদের না একই রকম ডেটা রয়েছে এবং না একই জিনিস object যাইহোক, আমরা যখন তাদের তুলনা করি, আমরা তাদের সমান তুলনা করতে চাই। এখানে যা ঘটছে তা হ'ল মনিটরের অবজেক্টটি __eq__পদ্ধতিটি কার্যকর করে ।

class Monitor(object):
    # ...

    def __eq__(self, other):
        return self.make == other.make and self.model == other.model

আপনার প্রশ্নের উত্তর দিচ্ছেন

তুলনা করার সময় None, সর্বদা ব্যবহার করুন is not। পাইথনে কোনওই সিঙ্গলটন নয় - স্মৃতিতে এর একমাত্র উদাহরণ রয়েছে।

পরিচয়ের তুলনা করে , এটি খুব দ্রুত সম্পাদন করা যেতে পারে। পাইথন যা আপনি উল্লেখ করছেন তার গ্লোবাল নন অবজেক্টের মতো একই মেমরি ঠিকানা রয়েছে কিনা তা যাচাই করে - দুটি সংখ্যার খুব, খুব দ্রুত তুলনা।

সমতার তুলনা করে পাইথনকে আপনার বস্তুর কোনও __eq__পদ্ধতি আছে কিনা তা সন্ধান করতে হবে । যদি এটি না হয়, তবে এটি প্রতিটি __eq__পদ্ধতির সন্ধান করে প্রতিটি সুপারক্লাস পরীক্ষা করে । যদি এটির সন্ধান করে তবে পাইথন এটিকে কল করে। এটি বিশেষত খারাপ হয় যদি __eq__পদ্ধতিটি ধীর গতিতে থাকে এবং তাত্ক্ষণিকভাবে ফিরে আসে না যখন লক্ষ্য করে যে অন্য বস্তুটি রয়েছে None

আপনি বাস্তবায়ন করেননি __eq__? তারপরে পাইথন সম্ভবত __eq__পদ্ধতিটি আবিষ্কার করবে objectএবং তার পরিবর্তে এটি ব্যবহার করবে - যা কেবল যাইহোক বস্তুর পরিচয় পরীক্ষা করে।

পাইথনের অন্যান্য বেশিরভাগ জিনিসের তুলনা করার সময় আপনি ব্যবহার করবেন !=


42

নিম্নোক্ত বিবেচনা কর:

class Bad(object):
    def __eq__(self, other):
        return True

c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)

1
এটি একটি খুব সহায়ক এবং সহজ উদাহরণ। ধন্যবাদ.
মিসরাফজাদেঃ

18

Noneএকটি সিঙ্গলটন, সুতরাং পরিচয় তুলনা সর্বদা কার্যকর হবে, যখন কোনও বস্তু সমতার তুলনাটি জাল করতে পারে .__eq__()


আহ আকর্ষণীয়! কোন পরিস্থিতিতে সমতা তুলনা বিটিডব্লু নকল করতে পারে? আমি অনুমান করছি এটির কোনওভাবে সুরক্ষা জড়িত।
viksit

1
এটি সমতা নকল করার বিষয়ে নয়, এটি সমতা বাস্তবায়নের বিষয়ে । কোনও বস্তুর সাথে কীভাবে অন্যটির তুলনা করা হয় তা নির্ধারণ করার অনেক কারণ রয়েছে।
থমাস ওয়াউটারস

1
আমি বলব এটি সুরক্ষা জড়িততার চেয়ে আরও বিভ্রান্তির সাথে জড়িত।
গ্রেগ হিউগিল

2
আমি এর বিরুদ্ধে জাল সাম্যতার কোনও কারণের পক্ষে আসিনি None, তবে Noneঅন্য ধরণের বিরুদ্ধে সাম্য প্রয়োগের পার্শ্ব প্রতিক্রিয়া হিসাবে সম্পর্কিত ভুল আচরণ হতে পারে। এটি এতটা সুরক্ষা জড়িত নয় যেহেতু এটি কেবল নির্ভুলতার অন্তর্ভুক্ত।
ইগনাসিও ওয়াজকেজ-আব্রামস

আহ যেভাবে, আমি দেখতে। স্পষ্টতা জন্য Thx।
viksit

10
>>> () হ'ল ()
সত্য
>>> 1 হচ্ছে 1
সত্য
>>> (1,) == (1,)
সত্য
>>> (1,) হ'ল (1,)
মিথ্যা
>>> এ = (1,)
>>> খ = ক
>>> ক খ
সত্য

কিছু বস্তু singletons হয়, এবং এইভাবে isতাদের সাথে সমতূল্য ==। বেশিরভাগ না।


4
এর বেশিরভাগই কেবল কাকতালীয় / বাস্তবায়নের বিশদ দ্বারা কাজ করে। ()এবং 1অন্তর্নিহিত একক না।
মাইক গ্রাহাম

1
CPython বাস্তবায়ন ইন, ছোট পূর্ণসংখ্যার ( -NSMALLNEGINTS <= n <= NSMALLPOSINTS) এবং খালি tuples হয় singletons। প্রকৃতপক্ষে এটি নথিভুক্ত বা গ্যারান্টিযুক্ত নয়, তবে এটি পরিবর্তনের সম্ভাবনা নেই।
ephemient

3
এটি কীভাবে কার্যকর করা হয় তবে তা অর্থবহ বা কার্যকর বা শিক্ষামূলক নয়।
মাইক গ্রাহাম 21

1
এবং বিশেষত সিপিথন কেবলমাত্র পাইথন বাস্তবায়ন নয়। পাইথন বাস্তবায়ন জুড়ে পরিবর্তিত হতে পারে এমন আচরণের উপর নির্ভর করা আমার কাছে সাধারণত খারাপ ধারণা would
আমি_ এবং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.