পাইথনে “যদি সামোবজ না:” কেন “যদি সামোবজ == কোনওই নয়:” এর চেয়ে ভাল?


127

আমি এর মতো কোডের বেশ কয়েকটি উদাহরণ দেখেছি:

if not someobj:
    #do something

তবে আমি ভাবছি না কেন:

if someobj == None:
    #do something

কোন পার্থক্য আছে? একজনের কি অন্যের চেয়ে সুবিধা রয়েছে?


13
সাধারণত 'সোমোবজ ইজ নন' এর চেয়ে 'সামোবজ == কিছুই নয়'
হারুন মেনপা

সিউডোকোডের কী হবে যদি এক্স কিছুই না হয়? নাকি X != None?
চার্লি পার্কার 18

এই প্রশ্নটি অন্যদের তুলনায় আরও ভারবস ... কুডোস ...
আলামিন

উত্তর:


187

প্রথম পরীক্ষায় পাইথন boolযদি বস্তুটি ইতিমধ্যে না হয় তবে তাকে কোনও মানতে রূপান্তরিত করার চেষ্টা করুন । মোটামুটিভাবে, আমরা বস্তুটি জিজ্ঞাসা করছি: আপনি অর্থবোধক বা না? এটি নিম্নলিখিত অ্যালগরিদম ব্যবহার করে করা হয়:

  1. যদি অবজেক্টটির একটি __nonzero__বিশেষ পদ্ধতি থাকে (যেমন সংখ্যার অন্তর্নির্মিতগুলি হয়, intএবং float), এটি এই পদ্ধতিটিকে কল করে। এটি হয় অবশ্যই boolসরাসরি ব্যবহৃত intহয় এমন একটি মান বা Falseশূন্যের সমান হলে বিবেচিত এমন একটি মান অবশ্যই দিতে হবে।

  2. অন্যথায়, যদি বস্তুর টি __len__বিশেষ পদ্ধতি (যেমন ধারক বিল্ট-ইন, না list, dict, set, tuple, এটা এই পদ্ধতি কল একটি ধারক বিবেচনা করা, ...) Falseযদি এটা খালি (দৈর্ঘ্য শূন্য)।

  3. অন্যথায়, অবজেক্টটি যদি কোনও ক্ষেত্রে Trueনা হয় তবে তা Noneবিবেচনা করা হয় False

দ্বিতীয় পরীক্ষায়, বস্তুটির সাথে সমতার জন্য তুলনা করা হয় None। এখানে আমরা বস্তুকে জিজ্ঞাসা করছি, "আপনি কি এই অন্যান্য মানের সমান?" এটি নিম্নলিখিত অ্যালগরিদম ব্যবহার করে করা হয়:

  1. যদি অবজেক্টটির কোনও __eq__পদ্ধতি থাকে তবে তাকে বলা হয়, এবং প্রত্যাবর্তনের মানটি একটি মানতে রূপান্তরিত boolহয় এবং এর ফলাফল নির্ধারণের জন্য ব্যবহৃত হয় if

  2. অন্যথায়, যদি বস্তুর কোনও __cmp__পদ্ধতি থাকে তবে তাকে বলা হয়। এই ফাংশনটি অবশ্যই intদুটি বস্তুর ক্রমকে নির্দেশ করে ফেরত দিতে হবে ( -1যদি self < other, 0যদি self == other, +1তবে self > other)।

  3. অন্যথায়, অবজেক্টটি পরিচয়ের জন্য তুলনা করা হয় (যেমন তারা একই বস্তুর রেফারেন্স হিসাবে isঅপারেটর দ্বারা পরীক্ষা করা যেতে পারে )।

isঅপারেটরটি ব্যবহার করে আরও একটি পরীক্ষা সম্ভব । আমরা অবজেক্টটিকে জিজ্ঞাসা করব, "আপনি কি এই নির্দিষ্ট বিষয়?"

সাধারণত, আমি অ-সংখ্যাগত মানগুলির সাথে প্রথম পরীক্ষাটি ব্যবহার করার অনুরোধ করব, যখন আপনি একই প্রকৃতির বস্তুর (দুটি স্ট্রিং, দুটি সংখ্যা, ...) তুলনা করতে চান তখন সাম্যতার জন্য পরীক্ষাটি ব্যবহার করতে এবং পরিচয় পরীক্ষা করার জন্য কেবল তখনই সেন্ডিনেল মান ব্যবহার করে ( Noneঅর্থ উদাহরণের জন্য সদস্য ক্ষেত্রের জন্য আরম্ভ করা হয় না, বা যখন getattrবা __getitem__পদ্ধতিগুলি ব্যবহার করা হয় )।

সংক্ষিপ্তসার হিসাবে, আমাদের আছে:

>>> class A(object):
...    def __repr__(self):
...        return 'A()'
...    def __nonzero__(self):
...        return False

>>> class B(object):
...    def __repr__(self):
...        return 'B()'
...    def __len__(self):
...        return 0

>>> class C(object):
...    def __repr__(self):
...        return 'C()'
...    def __cmp__(self, other):
...        return 0

>>> class D(object):
...    def __repr__(self):
...        return 'D()'
...    def __eq__(self, other):
...        return True

>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:
...     print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
...         (repr(obj), bool(obj), obj == None, obj is None)
  '': bool(obj) -> False, obj == None -> False, obj is None -> False
  (): bool(obj) -> False, obj == None -> False, obj is None -> False
  []: bool(obj) -> False, obj == None -> False, obj is None -> False
  {}: bool(obj) -> False, obj == None -> False, obj is None -> False
   0: bool(obj) -> False, obj == None -> False, obj is None -> False
 0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
 A(): bool(obj) -> False, obj == None -> False, obj is None -> False
 B(): bool(obj) -> False, obj == None -> False, obj is None -> False
 C(): bool(obj) ->  True, obj == None ->  True, obj is None -> False
 D(): bool(obj) ->  True, obj == None ->  True, obj is None -> False
None: bool(obj) -> False, obj == None ->  True, obj is None ->  True

4
যদিও প্রযুক্তিগতভাবে সঠিক, তবে এটি ব্যাখ্যা করে না যে টিপলস, তালিকাগুলি, ডিক্টস, স্টারস, ইউনিকোডস, ইনস, ফ্লোটস ইত্যাদির একটি ননজারো রয়েছে । কাস্টম নানজারো পদ্ধতির উপর নির্ভর করার চেয়ে বিল্ট-ইন টাইপের সত্য মানের উপর নির্ভর করা অনেক বেশি সাধারণ ।
ডিডিএ

50

এগুলি উভয়ই দুর্বল অভ্যাস। একসময়, আনুষঙ্গিকভাবে কোনওটিই নয় এবং মিথ্যাটিকে অনুরূপ হিসাবে গণ্য করা ঠিক ছিল বলে মনে করা হত। তবে পাইথন ২.২ যেহেতু এটি সেরা নীতি নয়।

প্রথমত, যখন আপনি কোনও if xবা if not xএক ধরণের পরীক্ষা করেন, পাইথনকে xস্পষ্টতই বুলিয়ান রূপান্তর করতে হয়। boolফাংশনটির নিয়মগুলি মিথ্যা বিষয়গুলির একটি ভেলাটিকে বর্ণনা করে; অন্য সব কিছুই সত্য। যদি x এর মানটি শুরু করতে সঠিকভাবে বুলেট না হয় তবে এই অন্তর্নিহিত রূপান্তরটি আসলে কিছু বলার স্পষ্ট উপায় নয়।

পাইথন ২.২ এর আগে কোনও বুল ফাংশন ছিল না, তাই এটি আরও কম পরিষ্কার ছিল।

দ্বিতীয়ত, আপনার সাথে সত্যই পরীক্ষা করা উচিত নয় == None। আপনার ব্যবহার করা উচিত is Noneএবং is not None

পাইথন কোডের জন্য পিইপি 8, স্টাইল গাইড দেখুন ।

- Comparisons to singletons like None should always be done with
  'is' or 'is not', never the equality operators.

  Also, beware of writing "if x" when you really mean "if x is not None"
  -- e.g. when testing whether a variable or argument that defaults to
  None was set to some other value.  The other value might have a type
  (such as a container) that could be false in a boolean context!

কয়টি সিলেটলেট আছে? পাঁচ: None, True, False, NotImplementedএবং Ellipsis। যেহেতু আপনি সত্যিই ব্যবহারের সম্ভাবনা NotImplementedবা না Ellipsis, এবং আপনি কখনই বলবেন না if x is True(কারণ এটি কেবল if xঅনেক পরিষ্কার) সুতরাং আপনি কেবল পরীক্ষা করবেন None


3
দ্বিতীয় ফর্মটি খারাপভাবে অনুশীলন নয়। পিইপি 8 দুটিবার x ব্যবহার করার পরামর্শ দেয় । প্রথমে সিক্যুয়েন্সগুলির জন্য (লেন ব্যবহারের পরিবর্তে) এবং তারপরে সত্য এবং মিথ্যা (ব্যবহারের পরিবর্তে)। কার্যতঃ সমস্ত পাইথন কোড আমি ব্যবহার করে দেখেছি x এবং যদি x নয়।
আন্তি রসিনেন

35

কারণ Noneএটিই কেবল মিথ্যা হিসাবে বিবেচিত হয় না।

if not False:
    print "False is false."
if not 0:
    print "0 is false."
if not []:
    print "An empty list is false."
if not ():
    print "An empty tuple is false."
if not {}:
    print "An empty dict is false."
if not "":
    print "An empty string is false."

False, 0, (), [], {}এবং ""থেকে সব আলাদা None, তাই আপনার দুই কোড স্নিপেট হয়, না সমতুল্য।

তদতিরিক্ত, নিম্নলিখিত বিবেচনা করুন:

>>> False == 0
True
>>> False == ()
False

if object:হয় না একটি সমতা চেক। 0, (), [], None, {}, ইত্যাদি হয় একে অপরের থেকে সব বিভিন্ন, কিন্তু তারা সব মূল্যায়নের মিথ্যাতে।

সংক্ষিপ্ত সার্কিট এক্সপ্রেশনগুলির পিছনে এটি "যাদু":

foo = bar and spam or eggs

যা সংক্ষিপ্ত:

if bar:
    foo = spam
else:
    foo = eggs

যদিও আপনার সত্যই লেখা উচিত:

foo = spam if bar else egg

আপনার শেষ প্রশ্ন সম্পর্কিত, তারা সমতুল্য।
সিলভাইন ডিফ্রেসনে

এবং উভয়ই ভুল কারণ "" মিথ্যা। দ্বিতীয়টি '("",) বা ("গুলি",)' পড়তে হবে। যাইহোক, পাইথনের আধুনিক সংস্করণগুলিতে একটি উপযুক্ত টের্নারি অপারেটর রয়েছে। এই ত্রুটি-প্রবণ হ্যাকটি বাতিল করা উচিত।
ddaa

4

পিইপি 8 - পাইথন কোডের জন্য স্টাইল গাইড ব্যবহার করার পরামর্শ দেয় আপনি যদি নন -নেসের জন্য পরীক্ষা করছেন তবে তা হয় বা না

- Comparisons to singletons like None should always be done with
  'is' or 'is not', never the equality operators.

অন্যদিকে আপনি যদি কোনও নন-নেসের চেয়ে বেশি পরীক্ষা করে নিচ্ছেন তবে আপনার বুলিয়ান অপারেটরটি ব্যবহার করা উচিত।


3

যদি তুমি জিজ্ঞাসা কর

if not spam:
    print "Sorry. No SPAM."

__nonzero__ পদ্ধতি স্প্যাম নামক পায়। পাইথন ম্যানুয়াল থেকে:

__nonzero__ ( স্ব ) সত্য মান পরীক্ষার প্রয়োগ এবং বিল্ট-ইন অপারেশন বুল ( ) প্রয়োগ করতে বলা হয়; মিথ্যা বা সত্য, বা তাদের পূর্ণসংখ্যার সমতুল্য 0 বা 1 প্রদান করা উচিত When যদি কোনও শ্রেণি __len __ () বা __nonzero __ () না হিসাবে সংজ্ঞা দেয় তবে এর সমস্ত দৃষ্টান্তটিকে সত্য বলে বিবেচনা করা হবে।

যদি তুমি জিজ্ঞাসা কর

if spam == None:
    print "Sorry. No SPAM here either."

__eq__ পদ্ধতি স্প্যাম আর্গুমেন্ট সহ নামক পরার কোনটি

কাস্টমাইজেশন সম্ভাবনার আরও তথ্যের জন্য https://docs.python.org/references/datamodel.html#basic- কাস্টমাইজেশন এ পাইথন ডকুমেন্টেশনটি দেখুন


2

এই দুটি তুলনা বিভিন্ন উদ্দেশ্যে পরিবেশন করে। কোনও কিছুর বুলিয়ান মানের জন্য প্রাক্তন চেকস, কোনটিই মান না দিয়ে পরিচয়ের জন্য দ্বিতীয় চেক।


1
একেবারে সঠিক হতে, দ্বিতীয় মানের জন্য-যা একটি নয় মান দিয়ে পরীক্ষা করে ... "someobj হয় কিছুই নয়" সনাক্তকরণের জন্য।
ম্যাথু ট্রেভর

0

একটির জন্য প্রথম উদাহরণটি ছোট এবং সুন্দর দেখায় looks অন্যান্য পোস্ট অনুসারে আপনি যা চয়ন করেন তা নির্ভর করে আপনি তুলনার সাথে কী করতে চান on


0

উত্তরটি হল, এটা নির্ভরশীল".

আমি প্রথম উদাহরণটি ব্যবহার করি যদি আমি 0, "", [] এবং মিথ্যা (সম্পূর্ণ নয় তালিকাটি) এই প্রসঙ্গে কোনওটির সমতুল্য না হয় consider


0

ব্যক্তিগতভাবে, আমি ভাষাগুলি জুড়ে একটি সামঞ্জস্যপূর্ণ পন্থা বেছে নিয়েছি: if (var)ভেরি বুলিয়ান হিসাবে ঘোষিত হলে (বা এরূপ হিসাবে সংজ্ঞায়িত করা হয়, সি তে আমাদের নির্দিষ্ট প্রকার নেই) কেবল তখনই আমি করি (বা সমতুল্য) do এমনকি আমি দুর্ঘটনাক্রমে অন্য ধরণের এখানে ব্যবহার করব না তা নিশ্চিত হওয়ার জন্য আমি এই ভেরিয়েবলগুলি একটি b(এমনকি এটি bVarআসলে হবে) দিয়ে উপসর্গ করেছি ।
আমি বুলিয়ান থেকে অন্তর্নিহিত castালাই পছন্দ করি না, এমনকি যখন অনেকগুলি, জটিল নিয়ম থাকে less

অবশ্যই, মানুষ মতানৈক্য হবে। কেউ কেউ আরও দূরে যান, আমি if (bVar == true)জাভা কোডে আমার কাজটিতে দেখি (আমার স্বাদের জন্য অত্যধিক অতিরিক্ত), অন্যরা খুব বেশি কমপ্যাক্ট সিনট্যাক্স পছন্দ করেন, যাচ্ছেন while (line = getNextLine())(আমার পক্ষে খুব অস্পষ্ট)।

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