الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

من شواذ بايثون - إحذر عند مقارنة كائنين بإستخدام Is

بدأه محمد سمير في 22 يونيو 2009 · 7 رد · 1,583 مشاهدة · في لغة Python
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله

ملاحظة غريبة عند مساواة رقمين في بايثون

لنفترض

a = 256
b = 256

عند إختبار

a is b

فالمتوقع أن يكون الناتج true

لكن جرب

c = 257
d = 257

عند إختبار

c is d

ستجد أن الناتج false

إليك التفسير:

في الحقيقة الحالة الثانية هي الأساس حيث أن is في بايثون تقارن كينونة العنصر نفسه و ليس قيمته

In Python, is tests for identity, not equality.

و على هذا فإن c كائن مستقل و d كائن مستقل أخر و لذلك c is not d.

لكن لماذا في الحالة الأولى عند مقارنة a و b تساوى الكائنين !!!

ذلك لأن مع بايثون الأعداد من -5 و حتى 256 مخزنة في الذاكرة "و ذلك لأسباب متعلقة بالأداء" و لذلك عندما أعطيت a و b قيمة داخل هذا النطاق من الأعداد (في حالتنا هذه 256) أصبح للكائنين نفس المرجع لنفس القيمة في الذاكرة مما أعطانا True عند المقارنة بينهما ب is.

الدرس المستفاد: لتقارن بين قيمتين لكائنين إستخدم == أفضل.

*هذه الملاحظة مرتبطة ب CPython و صاحب المقال الأصلي جربها مع بايثون 3 و أنا جربتها مع بايثون 2.6 و أعطت نفس النتيجة.

*عندما قمت بتجربتها مع Jython فكانت النتيجة True في نطاق الأعداد من -101 حتى 899.

*هل من أحد يجربها مع ironPython ؟

المقال الأصلي:

http://distilledb.com/blog/archives/date/2...r-equality.page

3

سبحانك اللهم و بحمدك ، أشهد أن لا إله إلا أنت ، أستغفرك ربي و أتوب إليك

مدونتي

http://www.facebook.com/brmjt

#2

السلام عليكم ...

لمحة جميلة أخي محمد :)

حتى في لغات أخرى كـ Java مثلاً هذا الشيء موجود....

معنى أننا نقارن كينونة العنصر, بدلاً من مقارنة القيم,

هو أننا نتحقق هل هو الكائن نفسه عن طريق الـ reference مثلاً, و ليس قيمة الكائنين,

فمثلاً في Java,

String first = "Khaled", second = "Khaled";
if(first == second)
	System.out.println("Yes, I will be written!");

و لكن لو قمت بالتالي ::

String first = "Khaled", second;
Scanner keyboard = new Scanner(System.in);
second = keyboard.next();
if(first == second)
	System.out.println("Yes, I will be written!");
else
	System.out.println("Comon, why they are not EQUAL ?");

و قمت بإدخال نفس القيمة التي أعطيناها لـ second في المثال الأول,

فإن الكائنان ليسا متساويان من ناحية الـ identity :)

و الصحيح أن نقوم بالتالي في Java إذا أردنا التحقق من المساواة ::

String first = "Khaled", second;
Scanner keyboard = new Scanner(System.in);
second = keyboard.next();
if(first.equals(second))
	System.out.println("Yes, I will be written!");
else
	System.out.println("Comon, why they are not EQUAL ?");

بالطبع في الحالة الأولى, الكائنان كانا متساويان من ناحية الـ identity لأن مترجم Java وجد أن النصين متشابهان تماماً, و بالتالي حجز لهما مكاناً واحداً و أشار إلى نفس المكان من first و second,

أما في الحالة الثانية, فالمترجم ليس موجوداً حتى يساعدنا :)

بالتأكيد المترجم استطاع فعل فعلته في الحالة الأولى لأن كائن النص في Java لا يمكن التعديل عليه Immutable و بالتالي لن يمكن تغيير النص الأصلي من أحد الـ references التي تشير إليه,

لاحظت أن بعض مبرمجي Java يقعون في هذا الخطأ و يعتقدون أن كائن النص متميز في Java عن البقية حيث أنه يمكن التحقق من المساواة باستخدام == بدلاً من equals,

شكراً على اللمحة الجميلة,

تحياتي ...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 22 يونيو 2009 في 01:51

4
#3

السلام عليكم أخي خالد

بل الشكر لك على إضافتك الجميلة, حقاً أفادتني كثيراً.

هل النقطة التي طرحتها ترتبط بمسألة هل الجافا تمرر بالقيمة أم بالمرجع؟

passing by reference or passing by value

قرأت في هذه المسألة و لم أستوعبها حتى الآن :)

لدي سؤال: بالنسبة ل JVM هل هناك قيم (أعداد) مخزنة في الذاكرة cashed مثل بايثون؟ لأن مسألة إعطاء True عند إختبار is مع Jython جعلتني أفكر هل الأعداد المخزنة مخزنة عن طريق مفسر جايثون أم عن طريق JVM.

إضافة للموضوع الأصلي:

جربت إختبار is مع PyS60 على نوكيا E71 و كانت النتيجة True لنطاق الأعداد من -2 إلى 100.

كما جربته مع IronPython 2.6b و كانت النتيجة False دائماً, إذن IronPython لا تحوي على Cashed Integers.

أي تعليق أو تصحيح أو توضيح مقبول بل و منتظر من جميع الإخوة :)

وفقكم الله

سبحانك اللهم و بحمدك ، أشهد أن لا إله إلا أنت ، أستغفرك ربي و أتوب إليك

مدونتي

http://www.facebook.com/brmjt

#4

السلام عليكــم ورحمـة الله وبركاتــه ،،

شكراً اخي محمد على الموضوع

بيستاهل خمس نجمات

و القسم بينقصو متل هي المواضيع و المعلومات و التجارب الشخصية

ما كنت عارفة بخصوص اعتماد Python على الترتيب range.

Thank you very much...

هون محوالتي في اثبات ذلك...

>>> a = 10

>>> b = 10

>>> a == b

True

>>> a is b

True

>>> #ولكن بعد تجاوز الترتيب عن 256

>>> a = 257

>>> b = 257

>>> # السطر التاني بيعطينا إجابة صائبة لأنها مقارنة عددية

>>> a == b

True

>>> # السطر التاني بيعطينا اجابة خاطئة لأنها مقارنة كينونية

>>> a is b

False

>>> # و الدليل بنستعمل الدالة آيدي للتحقق من زلك

>>> id( a )

20334400

>>> id( b )

20333840

>>> # الأرقام السابقة لكل كائن مختلفين تماماً عن بعض

>>> # بعكس الآيدي التالية لما بيكونوا ضمن الترتيب

>>> a = 10

>>> b = 10

>>> id( a )

505396888

>>> id( b )

505396888

>>> # شايفين التشابه بالعناوين بالزاكرة؟؟؟؟

>>> print("Bye...")

Bye...

>>>

معلومة ممتااااااازة كتير كتير كتير

موفقين يارب

Bye...

[وسط]

♥ Countess ♥

57899411.gif

♥

[/وسط]

#5

تقريبا الحالة الوحيدة اللى بستخدم فيها is هى عند التعامل مع None

http://docs.python.org/c-api/none.html

ميغسى ياحج محمد :D

تم تعديل هذه المشاركة بواسطة ahmed_youssef في 23 يونيو 2009 في 15:04

(map share people)

فضلا لاتقم بمراسلتي من أجل أسئلة لها أقسامها في المنتدى حتى تعم الفائدة على الجميع وللحصول على إجابات أفضل من أعضاء أكثر خبرة.
Weblog
@bitbucket
@xmonader

#6

الشاذ في الموضوع ليس ان is لا تعطي true للقيم المتساوية, بل الشاذ انها تعطي true للارقام دون 256,

حيث ان is منذ البداية لا علاقة لها بقيمة الاشياء المقارنة

#7
اقتباس
الشاذ في الموضوع ليس ان is لا تعطي true للقيم المتساوية, بل الشاذ انها تعطي true للارقام دون 256,

حيث ان is منذ البداية لا علاقة لها بقيمة الاشياء المقارنة

السلام عليكم أخي حسن .... ملاحظتك هي نفسها مدار الموضوع بالكامل

اقتباس
إليك التفسير:

في الحقيقة الحالة الثانية هي الأساس حيث أن is في بايثون تقارن كينونة العنصر نفسه و ليس قيمته

نقطة خارج الموضوع: مبروك أخي الكريم المركز الثاني في مسابقة المنتدى و إن كنت أرى من وجهة نظري أن برنامجك يستحق المركز الأول.

سبحانك اللهم و بحمدك ، أشهد أن لا إله إلا أنت ، أستغفرك ربي و أتوب إليك

مدونتي

http://www.facebook.com/brmjt

#8

شكرا اخي محمد الله يبارك فيك و عقبالك :)

انا نقطة اعتراضي بس على عبارة:

اقتباس
فالمتوقع أن يكون الناتج true

لاني ارى ان العكس هو الصحيح, فالمتوقع من is ان لا يكون الناتج True لمجرد تساوي القيمة المخزنة في كلا المتغيرين.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…