এই প্রশ্নের একটি মন্তব্যে , আমি একটি বিবৃতি দেখেছি যা ব্যবহারের সুপারিশ করেছে
result is not None
বনাম
result != None
আমি ভাবছিলাম যে পার্থক্যটি কী এবং কেন একজনের অপরটির চেয়ে সুপারিশ করা যেতে পারে?
এই প্রশ্নের একটি মন্তব্যে , আমি একটি বিবৃতি দেখেছি যা ব্যবহারের সুপারিশ করেছে
result is not None
বনাম
result != None
আমি ভাবছিলাম যে পার্থক্যটি কী এবং কেন একজনের অপরটির চেয়ে সুপারিশ করা যেতে পারে?
উত্তর:
==
একটি সমতা পরীক্ষা । এটি ডান হাতের পাশ এবং বাম হাতের সমান অবজেক্ট (তাদের __eq__
বা __cmp__
পদ্ধতি অনুসারে ) কিনা তা পরীক্ষা করে )
is
একটি পরিচয় পরীক্ষা । এটি ডান হাতের দিক এবং বাম হাতের দিকটি একই জিনিস কিনা তা পরীক্ষা করে। কোনও মেথকাকলগুলি করা হয় না, বস্তুগুলি is
অপারেশনকে প্রভাবিত করতে পারে না ।
আপনি is
(এবং is not
) সিঙ্গেলনের জন্য ব্যবহার করেন , যেমন None
আপনি যেখানে এমন বস্তুগুলির বিষয়ে চিন্তা করেন না যেগুলি যেগুলি ভান None
করতে চায় এবং যেখানে আপনি যখন তুলনা করার সময় ভাঙা বস্তুগুলির বিরুদ্ধে সুরক্ষা রাখতে চান None
।
None
কয়েকটি পদ্ধতি রয়েছে এবং প্রায় কোনও বৈশিষ্ট্য নেই। যদি আপনার __eq__
পরীক্ষাটি কোনও পদ্ধতি বা বৈশিষ্ট্য প্রত্যাশিত হয় তবে এটি ভেঙে যেতে পারে। def __eq__( self, other ): return self.size == other.size
। উদাহরণস্বরূপ, যদি other
ঘটে যায় তবে ভাঙ্গবে None
।
is
জাভা-র মতো ==
। পাইথন জাওয়ার ==
মতো .equals()
। অবশ্যই আপনি যদি জাভা জানেন তবে এটি সহায়তা করে।
is
এটি ===
(খুব সমান), এবং বিপরীতভাবে is not
এর মতো !==
(ঠিক সমান নয়)।
is not
একটি একক অপারেটর বা এটা শুধু ফল অস্বীকার করা হয় is
মত অভ্যন্তরীণভাবে not foo is bar
?
প্রথমে আমাকে কয়েক শর্তে যেতে দিন। আপনি যদি কেবল আপনার প্রশ্নের উত্তর চান তা চাইলে "আপনার প্রশ্নের উত্তর দেওয়ার জন্য" স্ক্রোল করুন।
অবজেক্টের পরিচয় : আপনি যখন কোনও অবজেক্ট তৈরি করেন, আপনি এটিকে একটি ভেরিয়েবলের জন্য বরাদ্দ করতে পারেন। এরপরে আপনি এটিকে অন্য ভেরিয়েবলকেও বরাদ্দ করতে পারেন। এবং অন্য.
>>> 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
এবং তার পরিবর্তে এটি ব্যবহার করবে - যা কেবল যাইহোক বস্তুর পরিচয় পরীক্ষা করে।
পাইথনের অন্যান্য বেশিরভাগ জিনিসের তুলনা করার সময় আপনি ব্যবহার করবেন !=
।
নিম্নোক্ত বিবেচনা কর:
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)
None
একটি সিঙ্গলটন, সুতরাং পরিচয় তুলনা সর্বদা কার্যকর হবে, যখন কোনও বস্তু সমতার তুলনাটি জাল করতে পারে .__eq__()
।
None
, তবে None
অন্য ধরণের বিরুদ্ধে সাম্য প্রয়োগের পার্শ্ব প্রতিক্রিয়া হিসাবে সম্পর্কিত ভুল আচরণ হতে পারে। এটি এতটা সুরক্ষা জড়িত নয় যেহেতু এটি কেবল নির্ভুলতার অন্তর্ভুক্ত।
>>> () হ'ল () সত্য >>> 1 হচ্ছে 1 সত্য >>> (1,) == (1,) সত্য >>> (1,) হ'ল (1,) মিথ্যা >>> এ = (1,) >>> খ = ক >>> ক খ সত্য
কিছু বস্তু singletons হয়, এবং এইভাবে is
তাদের সাথে সমতূল্য ==
। বেশিরভাগ না।
()
এবং 1
অন্তর্নিহিত একক না।
-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) এবং খালি tuples হয় singletons। প্রকৃতপক্ষে এটি নথিভুক্ত বা গ্যারান্টিযুক্ত নয়, তবে এটি পরিবর্তনের সম্ভাবনা নেই।