لماذا تكليف صواب / خطأ لا تعمل كما أتوقع؟
-
20-09-2019 - |
سؤال
وكجزء من الرد على سؤال آخر، كتبت التعليمة البرمجية التالية التي يبدو غريبا للوهلة الأولى السلوك:
print True # outputs true
True = False; print True # outputs false
True = True; print True # outputs false
True = not True; print True # outputs true
ويمكن لأحد أن يفسر هذا السلوك الغريب؟ أعتقد أن لها علاقة مع طراز كائن بيثون ولكن لست متأكدا.
وانها النسخة 2.5.2 تحت سيغوين.
المحلول
وبيثون ديه هذين (وغيرهم) المضمن الكائنات. هم كائنات عادلة. في البداية، لم يكن لديهم أي أسماء حتى الآن، ولكن لمعرفة ما نشير إليه، دعنا نسميها 0x600D
و0xBAD
.
وقبل البدء في تنفيذ برنامج نصي بيثون (2.x)، و يحصل بد من True
الاسم إلى 0x600D
الكائن، وFalse
اسم يحصل منضمة إلى 0xBAD
الكائن، وذلك عندما يشير البرنامج إلى True
، فإنه يبحث في 0x600D
.
ولأن 0x600D
و0xBAD
نعرف أنها تستخدم عادة من قبل True
أسماء وFalse
، وهذا ما الانتاج عندما تحصل على طباعتها، أي طريقة __str__
من عوائد 0x600D
'True'
وهلم جرا.
True = False
ويربط الآن True
اسم لكائن آخر. من الآن فصاعدا، كل من أسماء True
وFalse
الرجوع إلى نفس 0xBAD
الكائن، الذي، عند طباعتها، False
النواتج.
True = True
ولا حقا تفعل أي شيء: يستغرق الكائن الذي أشار إليه True
الاسم، ويربط الاسم الجديد (والكبار) True
لهذا الكائن. منذ (بسبب سابقة الخطوة) True
يشير إلى 0xBAD
قبل هذا، فإنه لا يزال يشير إلى 0xBAD
بعد ذلك. وبالتالي، لا يزال طباعة False
النواتج.
True = not True
ويأخذ البداية كان الهدف أن True
اسم لا بد أن، وهو 0xBAD
. ويعطي هذا الكائن إلى المشغل not
. not
لا يهتم (أو معرفة) ما اسم يستخدم هنا للإشارة إلى 0xBAD
، فهو يعرف ذلك تماما عندما تعطى 0xBAD
يجب أن تعيد 0x600D
. ثم تعطى هذه القيمة العودة إلى =
عامل التعيين، ربط True
اسم لهذا الكائن.
ومنذ True
اسم الآن مرة أخرى يشير إلى 0x600D
الكائن، داعيا print True
مخرجات True
، والعالم هي جيدة مرة أخرى.
نصائح أخرى
وتخيل هذا بدلا من ذلك:
A = True
B = False
print A # true
A = B; print A # false
A = A; print A # false, because A is still false from before
A = not A; print A # true, because A was false, so not A is true
ونفس الشيء بالضبط يجري، ولكن في الإصدار الخاص بك انها مربكة، لأنك لا تتوقع أن تتمكن من إعادة تحديد الصواب والخطأ.
وفي 2.x، الصواب والخطأ ليست الكلمات الرئيسية لذلك فمن الممكن الظل الإضافية التي بنيت في هذه الطريقة.
ويمكنك التحقق ما إذا كان صواب / خطأ هو الكلمة:
>>> import keyword
>>> keyword.iskeyword('True')
False
ولأنها ليست (في نسختي)، وتكليف وسائل عادلة صحيح = كاذبة "صحيح" هو آخر "متغير" اسم.
ويمكن بسهولة استعادة القيم الأصلية باستخدام مقارنات منطقية بسيطة:
True = 1==1
False = 1==0
وأو عن طريق تحويل الحرفية صحيح لbools:
True = bool(1) # actually every number except 0 works
False = bool(0)