هل هناك فرق بين "foo is لا شيء" و"foo == لا شيء"؟

StackOverflow https://stackoverflow.com/questions/26595

  •  09-06-2019
  •  | 
  •  

سؤال

هل هناك فرق بين:

if foo is None: pass

و

if foo == None: pass

التقليد الذي رأيته في معظم أكواد بايثون (والكود الذي أكتبه بنفسي) هو الأول، لكنني عثرت مؤخرًا على كود يستخدم الأخير.لا شيء هو مثيل (والمثيل الوحيد، IIRC) لـ NonType، لذا لا ينبغي أن يكون الأمر مهمًا، أليس كذلك؟هل هناك أي ظروف قد يكون فيها ذلك؟

هل كانت مفيدة؟

المحلول

is يعود دائما True إذا كان يقارن نفس مثيل الكائن

بينما == يتم تحديده في النهاية بواسطة __eq__() طريقة

أي.


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

>>> f = Foo()
>>> f == None
True
>>> f is None
False

نصائح أخرى

قد ترغب في قراءة هذا هوية الكائن والتكافؤ.

يتم استخدام العبارة 'is' لهوية الكائن، فهي تتحقق مما إذا كانت الكائنات تشير إلى نفس المثيل (نفس العنوان في الذاكرة).

وتشير العبارة '==' إلى المساواة (نفس القيمة).

كلمة تحذير:

if foo:
  # do something

يكون لا بالضبط مثل:

if x is not None:
  # do something

الأول هو اختبار قيمة منطقية ويمكن تقييمه بالخطأ في سياقات مختلفة.هناك عدد من الأشياء التي تمثل خطأ في اختبارات القيمة المنطقية، على سبيل المثال الحاويات الفارغة والقيم المنطقية.لا يتم تقييم أي شيء أيضًا على أنه خطأ في هذه الحالة ولكن الأشياء الأخرى تفعل ذلك أيضًا.

(ob1 is ob2) يساوي (id(ob1) == id(ob2))

السبب foo is None الطريقة المفضلة هي أنك قد تتعامل مع كائن يحدد ما هو خاص به __eq__, ، وهذا يحدد الكائن بأنه يساوي لا شيء.لذا، استخدم دائمًا foo is None إذا كنت بحاجة لمعرفة ما إذا كان في الواقع None.

لا يوجد فرق لأن الأشياء المتطابقة ستكون متساوية بالطبع.لكن، بيب 8 ينص بوضوح على أنه يجب عليك استخدامه is:

يجب دائمًا إجراء المقارنات مع المفردات مثل لا شيء مع is أو لا، وليس مع عوامل المساواة أبدًا.

is اختبارات الهوية, لا المساواة.بالنسبة لبيانك foo is none, تقوم Python ببساطة بمقارنة عنوان ذاكرة الكائنات.هذا يعني أنك تطرح السؤال "هل لدي اسمين لنفس الكائن؟"

== ومن ناحية أخرى اختبارات المساواة على النحو الذي يحدده __eq__() طريقة.ولا يهتم بالهوية.

In [102]: x, y, z = 2, 2, 2.0

In [103]: id(x), id(y), id(z)
Out[103]: (38641984, 38641984, 48420880)

In [104]: x is y
Out[104]: True

In [105]: x == y
Out[105]: True

In [106]: x is z
Out[106]: False

In [107]: x == z
Out[107]: True

None هو مشغل مفرد.لذا None is None هو دائما صحيح.

In [101]: None is None
Out[101]: True

بالنسبة إلى لا شيء، لا ينبغي أن يكون هناك فرق بين المساواة (==) والهوية (هو).من المحتمل أن يقوم NonType بإرجاع الهوية للمساواة.نظرًا لأن لا شيء هو المثيل الوحيد الذي يمكنك إجراؤه لـ NonType (أعتقد أن هذا صحيح)، فإن العمليتين متماثلتان.في حالة الأنواع الأخرى، ليس هذا هو الحال دائمًا.على سبيل المثال:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

سيؤدي هذا إلى طباعة "يساوي" نظرًا لأن القوائم تحتوي على عملية مقارنة ليست هي الإرجاع الافتراضي للهوية.

@جيسون:

أوصي باستخدام شيء أكثر على غرار

if foo:
    #foo isn't None
else:
    #foo is None

لا أحب استخدام "if foo:" إلا إذا كان foo يمثل قيمة منطقية حقًا (على سبيل المثال.0 أو 1).إذا كان foo عبارة عن سلسلة أو كائن أو أي شيء آخر، فقد يعمل "if foo:"، لكنه يبدو وكأنه اختصار بطيء بالنسبة لي.إذا كنت تتحقق لمعرفة ما إذا كانت x لا شيء، فقل "إذا كانت x لا شيء:".

المزيد من التفاصيل:

  1. ال is جملة يتحقق في الواقع إذا كان الاثنان objectS في نفس موقع الذاكرة أم لا.أي ما إذا كان كلاهما يشيران إلى نفس موقع الذاكرة ولديهما نفس الشيء id.

  2. نتيجة لـ 1، is يضمن ما إذا كان الاثنان ممثلين معجميًا أم لا objects لها سمات متطابقة (سمات السمات...) أم لا

  3. إنشاء مثيل للأنواع البدائية مثل bool, int, string(مع بعض الاستثناءات)، NoneType سيكون لها نفس القيمة دائمًا في نفس موقع الذاكرة.

على سبيل المثال

>>> int(1) is int(1)
True
>>> str("abcd") is str("abcd")
True
>>> bool(1) is bool(2)
True
>>> bool(0) is bool(0)
True
>>> bool(0)
False
>>> bool(1)
True

ومنذ ذلك الحين NoneType يمكن أن يكون هناك مثيل واحد فقط لنفسه في جدول "البحث" الخاص ببايثون، وبالتالي فإن الأول والأخير هما أكثر من أسلوب برمجة للمطور الذي كتب الكود (ربما من أجل الاتساق) بدلاً من وجود أي سبب منطقي دقيق لاختيار واحد على الآخر.

استنتاج جون ماشين ذلك None إن المفردة هي نتيجة يدعمها هذا الكود.

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

منذ None هو مفرد، x == None و x is None سيكون لها نفس النتيجة.لكن من وجهة نظري الجمالية x == None هو الأفضل.

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top