যদি A বনাম যদি A না হয় তবে:


154

ন্ন:

if A:

পরিবর্তে

if A is not None:

পরেরটি মনে হয় তাই ভার্জোজ। পার্থক্য আছে কি?

উত্তর:


149

বিবৃতি

if A:

কল করবে A.__nonzero__()( বিশেষ পদ্ধতির নাম ডকুমেন্টেশন দেখুন) এবং সেই ফাংশনের রিটার্ন মানটি ব্যবহার করবে। এখানে সংক্ষিপ্তসার:

object.__nonzero__(self)

সত্য মান পরীক্ষা এবং বিল্ট-ইন অপারেশন বাস্তবায়নের জন্য আহ্বান bool(); ফিরে আসতে হবে Falseবা True, বা তাদের পূর্ণসংখ্যার সমতুল্য 0বা 1। এই পদ্ধতিটি সংজ্ঞায়িত না __len__()হলে তাকে বলা হয়, এটি সংজ্ঞায়িত হলে এবং অবজেক্টটিকে সত্য হিসাবে বিবেচনা করা হয় যদি এর ফলাফলটি ননজারো হয়। যদি কোনও শ্রেণি বা উভয়কেই সংজ্ঞায়িত করে না __len__()তবে এর __nonzero__()সমস্ত উদাহরণ সত্য হিসাবে বিবেচিত হবে।

অন্য দিকে,

if A is not None:

এটি একই কিনা তা দেখার জন্য কেবলমাত্র রেফারেন্সের Aসাথে তুলনা করে None


4
A is not Noneকাজটি করার চেয়ে খুব কম কাজ
হওয়ায়

40
@gnibbler আমার পরীক্ষাগুলি অনুসারে নয়। if object(): passপ্রতি লুপে ~ 0.130 ইউজেক, যখন if object() is not None: pass~ 0.135 ইউএসসি। যাইহোক, এই দুটিয়ের মধ্যে চয়ন করার জন্য আপনার পারফরম্যান্স ব্যবহার করা উচিত নয়, তবে তারা যেভাবে কাজ করে তার মধ্যে পার্থক্যগুলি দেখুন, কারণ তারা সমতুল্য নয়
লরিজ ভি ভি থালো

1
@gnibbler if A is not Noneধীর বলে মনে হচ্ছে কারণ এটি তুলনা এবং বিল্টিন সিঙ্গলটনকে Noneমধ্যস্থতাকারী পদক্ষেপ হিসাবে তুলনা করার জন্য A(এটি একবার দেখুন dis.dis()) লোড করা দরকার । আমি ভুল হলে আমাকে সংশোধন করুন তবে if A:আরও কার্যকর বলে মনে হচ্ছে আপনি যত তাড়াতাড়ি সত্যের মূল্য পরীক্ষা করতে চান এবং Noneপরিচয়টি নয়।
cedbeu

2
@cedbeu, এ এর ​​মান উপর নির্ভর করে বলে মনে হচ্ছে আমি এখন পরীক্ষা করেছি এর python -m timeit -s"a=0" "if a: pass" "else: pass"চেয়ে দ্রুত python -m timeit -s"a=0" "if a is None: pass" "else: pass"তবে python -m timeit -s"a=1" "if a: pass" "else: pass"ধীর। প্ল্যাটফর্ম নির্ভর হতে পারে, আপনি একই ফলাফল পান কিনা তা দেখুন
জন লা রুই

2
@cedbeu, পাইথন 3 এ তারা সবাই অনেক দ্রুত, তবে is Noneপরীক্ষাটি আমার পক্ষে সত্যই সবচেয়ে ধীর ছিল। পাইপিতে তারা সবাই একই মাপলেন :)
জন লা রোয়

51

পিইপি 8 তে লেখা আছে :

  • মত singletons তুলনা কোনটি সর্বদা 'হল' বা সম্পন্ন করতে হবে না সমতা অপারেটর নয় ',

    এছাড়াও, "if x" লেখার বিষয়ে যখন আপনি সত্যিকার অর্থে "যদি x কিছুই নয়" লেখার বিষয়ে সতর্ক থাকুন - উদাহরণস্বরূপ যখন কোনও ভেরিয়েবল বা আর্গুমেন্ট যা কোনওটির কাছে ডিফল্ট হয় না তা অন্য কোনও মানকে সেট করা হয়েছিল কিনা তা পরীক্ষা করার সময়। অন্য মানটির মধ্যে একটি ধরণের (যেমন একটি ধারক) থাকতে পারে যা বুলিয়ান প্রসঙ্গে মিথ্যা হতে পারে!


7
এমএমএমএইচ এটি খুব স্পষ্ট নয়, তবে ওপি তে সাড়া দেয় না। পিইপিতে স্বয়ংক্রিয় পুনঃনির্দেশ সবসময় ভাল উত্তর হয় না। খুব সহজেই কেউ সিঙ্গলটনের সাথে পরিচয় পরীক্ষায় আগ্রহী হন না None, তবে কেবল সত্যের মূল্য পরীক্ষায় । এই ক্ষেত্রে, if A:আরও দক্ষ বলে মনে হয় (ক নিতে dis.dis()সেখানে builtin লোড অতিরিক্ত পদক্ষেপ, Noneএবং তুলনা সঙ্গে if A is not None:যখন মাত্র, jump_ifঅন্যান্য ক্ষেত্রে)।
সিডবেউ

29
if x: #x is treated True except for all empty data types [],{},(),'',0 False, and None

সুতরাং এটি যেমন হয় না

if x is not None # which works only on None

17

যথাযথ ফলাফল না থাকলে প্রচুর ফাংশন কিছুই দেয় না। উদাহরণস্বরূপ, .first()ফলাফলের কোনও সারি না থাকলে কোনও এসকিউএএলএলকেমি ক্যোয়ারির পদ্ধতি কোনওটিই প্রত্যাবর্তন করে না। মনে করুন আপনি এমন একটি মান বাছাই করছেন যা 0 প্রত্যাবর্তন করতে পারে এবং এটি জানতে হবে এটি আসলে 0 কিনা বা ক্যোয়ারীর কোনও ফল ছিল না কিনা।

একটি সাধারণ প্রথা হ'ল কোনও ফাংশন বা পদ্ধতির alচ্ছিক যুক্তিটি কোনওটির ডিফল্ট মান নয় এবং তারপরে সেই মানটি কোনওটি নয় কিনা এটি নির্দিষ্ট করা হয়েছে কিনা তা পরীক্ষা করা। উদাহরণ স্বরূপ:

def spam(eggs=None):
    if eggs is None:
        eggs = retrievefromconfigfile()

এর সাথে তুলনা করুন:

def spam(eggs=None):
    if not eggs:
        eggs = retrievefromconfigfile()

পরবর্তীকালে, যদি আপনি ফোন করেন spam(0)বা কী হয় spam([])? ফাংশনটি (ভুলভাবে) সনাক্ত করবে যে আপনি কোনও মান পাস করেন নি eggsএবং আপনার জন্য একটি ডিফল্ট মান গণনা করবে। এটি সম্ভবত আপনি চান না।

অথবা "প্রদত্ত অ্যাকাউন্টের জন্য লেনদেনের তালিকা ফিরিয়ে দিন" এর মতো কোনও পদ্ধতি কল্পনা করুন। যদি অ্যাকাউন্টটি না থাকে তবে এটি কোনওটিই ফেরত দিতে পারে না। এটি খালি তালিকা ফিরিয়ে দেওয়ার চেয়ে আলাদা (যার অর্থ "এই অ্যাকাউন্টটি বিদ্যমান তবে লেনদেন রেকর্ড করা হয়নি)।

শেষ পর্যন্ত, ডাটাবেস স্টাফ ফিরে। NULL এবং একটি খালি স্ট্রিংয়ের মধ্যে একটি বড় পার্থক্য রয়েছে। একটি খালি স্ট্রিং সাধারণত বলে "এখানে একটি মান আছে, এবং সেই মানটি কিছুই নয়"। NULL বলে "এই মানটি প্রবেশ করা হয়নি।"

এই প্রতিটি ক্ষেত্রেই আপনি ব্যবহার করতে চান if A is None। আপনি একটি নির্দিষ্ট মান পরীক্ষা করছেন - কিছুই নয় - কেবল "মিথ্যাতে কাস্ট করার জন্য ঘটে এমন কোনও মান" নয়।


10

তারা খুব আলাদা জিনিস করে

নিচে চেক যদি একটি মান ছাড়া কিছু আছে False, [], None, ''এবং 0। এটি এ এর মান পরীক্ষা করে

if A:

নীচে চেক করে নিন যে এ-এর চেয়ে আলাদা কোনও বস্তু কিনা। এটি এ এবং কোনওটির রেফারেন্স (মেমরি ঠিকানা) পরীক্ষা করে এবং তুলনা করে ।

if A is not None:

আপডেট: আরও ব্যাখ্যা

অনেক সময় দু'জন একই কাজ করে বলে মনে হয় তাই প্রচুর লোক একে অপরকে ব্যবহার করে - এটি সত্যিই খারাপ ধারণা। ইন্টার্নারিং বা অন্য কোনও কিছুর মতো দোভাষী / সংকলকটির অপ্টিমাইজেশনের কারণে দু'জন একই ফলাফল দেওয়ার কারণটি অনেকবার খাঁটি কাকতালীয় কারণে ।

এই অপটিমাইজেশনগুলি মনে রেখে, একই মানের পূর্ণসংখ্যা এবং স্ট্রিংগুলি একই মেমরি স্পেস ব্যবহার করে শেষ হয়। এটি সম্ভবত ব্যাখ্যা করে যে দুটি পৃথক স্ট্রিং কেন একই রকম হয় act

> a = 'test'
> b = 'test'
> a is b
True
> a == b
True

অন্যান্য জিনিস যদিও একই আচরণ করে না ..

> a = []
> b = []
> a is b
False
> a == b
True

দুটি তালিকার স্পষ্টতই তাদের নিজস্ব স্মৃতি রয়েছে। আশ্চর্যজনকভাবে টিপলস স্ট্রিংয়ের মতো আচরণ করে।

> a = ()
> b = ()
> a is b
True
> a == b
True

সম্ভবত এটি কারণ টিউপলগুলি পরিবর্তন না করার গ্যারান্টিযুক্ত, সুতরাং একই স্মৃতি পুনরায় ব্যবহার করা বোধগম্য।

এর নীচে লাইনটি আপনি কাকতালীয় উপর নির্ভর করতে পারবেন না । এটি হাঁসের মতো ঘুরে বেড়ানোর কারণে এর অর্থ এটি একটি হাঁস নয়। ব্যবহারের isএবং ==আপনি কি সত্যিই চেক করতে চান উপর নির্ভর করে। এই বিষয়গুলি ডিবাগ করা কঠিন কারণ isগদ্যের মতো পাঠ করা হয় যে আমরা প্রায়শই এটির উপরে ঝাঁকিয়ে পড়েছি।


Noneএটি একটি সিঙ্গলটন, এটি বাস্তবায়নের বিশদ নয় (ইনট বা স্ট্রিং ইন্টার্নিংয়ের বিপরীতে)। আমি নিশ্চিত নই যে আপনি যা বলতে চাইছেন আমি তা অনুসরণ করি।
লেভ লেভিটস্কি

@ লাইভলভিটস্কি আমার বক্তব্য ইন্টার্নিংয়ের Noneচেয়ে intবা তার strকারণে আলাদা আচরণ করে না । আমার বক্তব্যটি হ'ল isএবং ==বিভিন্ন জিনিস পরীক্ষা করে দেখছেন; প্রথমে একটি মেমরি ঠিকানা পরীক্ষা করে, দ্বিতীয়টি মেমরি ঠিকানার সামগ্রীগুলি পরীক্ষা করে।
পিথিকোস

@ লাইভলভিটস্কি আমার উত্তরটি এটিকে আরও হজম করার জন্য এখন সম্পাদনা করেছি।
পিথিকোস

7

if A: যদি এ 0 হয়, মিথ্যা, খালি স্ট্রিং, খালি তালিকা বা কোনও না হয় তবে এটি মিথ্যা প্রমাণিত হবে, যা অনাকাঙ্ক্ষিত ফলাফলের দিকে নিয়ে যেতে পারে।


1
এবং অন্যান্য অনেকগুলি মান যেমন খালি তালিকা, খালি সেট, খালি টিপল ইত্যাদি মূলত ডকস.পাইথন.আর / 3 / লিবারি / স্টাড্ডিপস html # truth- value- testing অনুযায়ী সত্য নয় এমন কিছু ।
জারোমড

6

বেশিরভাগ গাইড আমি দেখেছি যে আপনার ব্যবহার করা উচিত

যদি একটি:

আপনার আরও নির্দিষ্ট হওয়ার কারণ না থাকলে।

কিছুটা সামান্য পার্থক্য রয়েছে। আর কিছুই নেই যা ভুয়া প্রত্যাবর্তন করে, উদাহরণস্বরূপ খালি তালিকা বা 0, সুতরাং এটি কী আপনি সত্যিকারের জন্য পরীক্ষা করছেন তা চিন্তা করুন।


5

পাইথনের কোনওটিই বিশেষ মান নয় যা সাধারণত একটি অবিচ্ছিন্ন ভেরিয়েবল ডিজাইন করে। আপনি যে বিশেষ মানটি ব্যবহার করেন তাতে এটির কোনও বিশেষ মূল্য নেই কিনা তা পরীক্ষা করতে:

if A is not None

মিথ্যা মানগুলি পাইথনের বস্তুর একটি বিশেষ শ্রেণি (উদাঃ মিথ্যা, [])। A টি মিথ্যা ব্যবহার কিনা তা পরীক্ষা করতে:

if not A

সুতরাং, দুটি এক্সপ্রেশন একই নয় এবং আপনি এগুলি প্রতিশব্দ হিসাবে ভাল আচরণ করবেন না।


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


এটি ভুল নয় যে এই উত্তরটি ইতিমধ্যে এটি কভার করে।
মকোটো

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

ঠিক আছে, এই অনুমানটি অসম্পূর্ণ। এটি ভুল বা সহজভাবে কার্যকর নাও হতে পারে। যেহেতু আমি যেমন বলেছি আপনার উত্তরটি ইতিমধ্যে আচ্ছাদিত ছিল তাই আমি নিশ্চিত যে এটি কার্যকর it's
মাকোটো

4

ইহা পারিপার্শ্বিক অবস্থা উপর নির্ভর করে।

আমি if A:যখন Aএক ধরণের সংগ্রহের প্রত্যাশা করছি তখন আমি ব্যবহার করি এবং সংগ্রহটি খালি না হলে কেবলমাত্র ব্লকটি সম্পাদন করতে চাই। এটি কলারকে কোনও ভাল আচরণের সংগ্রহ, খালি বা না করে পাস করার অনুমতি দেয় এবং আমার প্রত্যাশা অনুযায়ী এটি করতে দেয়। এটি ব্লকের কার্য সম্পাদনকে মঞ্জুরি দেয় Noneএবং Falseদমন করতে পারে যা কলিং কোডের জন্য মাঝে মাঝে সুবিধাজনক।

OTOH, যদি আমি Aকিছু সম্পূর্ণ স্বেচ্ছাসেবী বস্তু হিসাবে প্রত্যাশা করি তবে এটির সাথে খেলাপি হতে পারে None, তবে আমি সর্বদা ব্যবহার করি if A is not None, কারণ কলিং কোডটি ইচ্ছাকৃতভাবে একটি খালি সংগ্রহ, খালি স্ট্রিং, বা 0-মূল্যবান সংখ্যার প্রকারের কোনও রেফারেন্স পেরিয়ে যেতে পারে বা বুলিয়ান False, বা কিছু শ্রেণীর উদাহরণ যা বুলিয়ান প্রসঙ্গে মিথ্যা বলে মনে হয়।

এবং অন্যদিকে, আমি যদি Aআরও কিছু নির্দিষ্ট জিনিস হওয়ার প্রত্যাশা করি (উদাহরণস্বরূপ যে শ্রেণীর উদাহরণগুলির জন্য আমি পদ্ধতিগুলির কল করতে যাচ্ছি) তবে এটি Noneডিফল্ট হতে পারে এবং আমি ডিফল্ট বুলিয়ান রূপান্তরকে একটি হিসাবে বিবেচনা করি শ্রেণীর সম্পত্তিটি আমি সমস্ত সাবক্লাসে প্রয়োগ করতে আপত্তি করি না, তবে আমি কেবল মাত্র if A:12 টি অক্ষর টাইপ করার ভয়ানক বোঝা আমার আঙ্গুলগুলি সংরক্ষণ করতে ব্যবহার করব ।


3

আমি ডাকা একটি ফাইল তৈরি করেছি test.pyএবং এটিকে দোভাষীর উপর চালিয়েছি। আপনি কী চান তা পরিবর্তন করতে পারেন, পর্দার আড়ালে কীভাবে জিনিস চলছে তা পরীক্ষা করে দেখতে।

import dis

def func1():

    matchesIterator = None

    if matchesIterator:

        print( "On if." );

def func2():

    matchesIterator = None

    if matchesIterator is not None:

        print( "On if." );

print( "\nFunction 1" );
dis.dis(func1)

print( "\nFunction 2" );
dis.dis(func2)

এটি সংশ্লেষকারী পার্থক্য:

উৎস:

>>> import importlib
>>> reload( test )

Function 1
  6           0 LOAD_CONST               0 (None)
              3 STORE_FAST               0 (matchesIterator)

  8           6 LOAD_FAST                0 (matchesIterator)
              9 POP_JUMP_IF_FALSE       20

 10          12 LOAD_CONST               1 ('On if.')
             15 PRINT_ITEM
             16 PRINT_NEWLINE
             17 JUMP_FORWARD             0 (to 20)
        >>   20 LOAD_CONST               0 (None)
             23 RETURN_VALUE

Function 2
 14           0 LOAD_CONST               0 (None)
              3 STORE_FAST               0 (matchesIterator)

 16           6 LOAD_FAST                0 (matchesIterator)
              9 LOAD_CONST               0 (None)
             12 COMPARE_OP               9 (is not)
             15 POP_JUMP_IF_FALSE       26

 18          18 LOAD_CONST               1 ('On if.')
             21 PRINT_ITEM
             22 PRINT_NEWLINE
             23 JUMP_FORWARD             0 (to 26)
        >>   26 LOAD_CONST               0 (None)
             29 RETURN_VALUE
<module 'test' from 'test.py'>

2

পূর্ববর্তীটি আরও পাইথোনিক (আরও ভাল আদর্শের কোড) তবে এ ফলস (কোনওটি নয়) ব্লকটি কার্যকর করবেন না।


7
-1। @ ক্লেশ যেমন উল্লেখ করেছে, পিইপি 8 ব্যবহার করতে বলেছে is/is not None। পিইপি 8 অনুসরণ করে পাইথোনিক। দুটি পরীক্ষাও আলাদা
জে কটন

1

অজগর> = 2.6,

যদি আমরা যেমন লিখি

if A:

হিসাবে সতর্কতা উত্পন্ন করবে,

ফিউচার ওয়ার্নিং: এই পদ্ধতির আচরণ ভবিষ্যতের সংস্করণগুলিতে পরিবর্তিত হবে। পরিবর্তে নির্দিষ্ট 'লেন (এলেম)' বা 'এলেম নয় কেউ নয়' পরীক্ষাটি ব্যবহার করুন।

সুতরাং আমরা ব্যবহার করতে পারেন

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