python - क्यों(0-6) है-6=झूठा?




debugging integer (3)

-5 से 256 समावेशी के सभी पूर्णांक को वैश्विक वस्तुएं कैपिथॉन के साथ एक ही पते साझा करने के रूप में कैश की जाती हैं, इस प्रकार परीक्षण पास होता है।

इस आर्टिफैक्ट को http://www.laurentluce.com/posts/python-integer-objects-implementation/ में विस्तार से समझाया गया है, और हम वर्तमान स्रोत कोड http://hg.python.org/cpython/file/tip/Objects/longobject.c

छोटे पूर्णांक को संदर्भित करने के लिए एक विशिष्ट संरचना का उपयोग किया जाता है और उन्हें साझा किया जाता है ताकि पहुंच तेज हो। यह पूर्णांक वस्तुओं के लिए 262 पॉइंटर्स की एक सरणी है। उन पूर्णांक ऑब्जेक्ट्स को ऊपर वर्णित पूर्णांक ऑब्जेक्ट्स के ब्लॉक में प्रारंभिकरण के दौरान आवंटित किया जाता है। छोटी पूर्णांक सीमा -5 से 257 तक है। कई पायथन कार्यक्रम उस सीमा में पूर्णांक का उपयोग करके बहुत समय व्यतीत करते हैं, इसलिए यह एक स्मार्ट निर्णय है।

यह केवल सीपीथॉन का कार्यान्वयन विवरण है और आपको इस पर भरोसा नहीं करना चाहिए। उदाहरण के लिए, PyPy ने खुद को वापस करने के लिए पूर्णांक की id लागू की, इसलिए (0-6) is -6 हमेशा सत्य है, भले ही वे आंतरिक रूप से "अलग-अलग वस्तुएं" हों; यह आपको यह कॉन्फ़िगर करने की अनुमति देता है कि इस पूर्णांक कैशिंग को सक्षम करना है, और यहां तक ​​कि निचले और ऊपरी सीमाएं भी सेट करें। लेकिन सामान्य रूप से, विभिन्न उत्पत्ति से पुनर्प्राप्त वस्तुओं समान नहीं होंगे। यदि आप समानता की तुलना करना चाहते हैं, तो बस == उपयोग करें।

संभावित डुप्लिकेट:
पायथन "है" ऑपरेटर पूर्णांक के साथ अप्रत्याशित रूप से व्यवहार करता है

आज मैंने अपनी परियोजना को डीबग करने की कोशिश की और विश्लेषण के कुछ घंटों के बाद मुझे यह मिल गया:

>>> (0-6) is -6
False

परंतु,

>>> (0-5) is -5
True

क्या आप मुझे समझा सकते हैं, क्यों? शायद यह किसी तरह का बग या बहुत अजीब व्यवहार है।

> Python 2.7.3 (default, Apr 24 2012, 00:00:54) [GCC 4.7.0 20120414 (prerelease)] on linux2
>>> type(0-6) 
<type 'int'>
>>> type(-6) 
<type 'int'>
>>> type((0-6) is -6)
<type 'bool'>
>>> 

ऐसा इसलिए हो रहा है क्योंकि सीपीथन कुछ छोटे पूर्णांक और छोटे तारों को कैश करता है और उस वस्तु के प्रत्येक उदाहरण को एक ही id()

(0-5) और -5 पास id() लिए समान मान है, जो 0-6 और -6 लिए सत्य नहीं है

>>> id((0-6))
12064324
>>> id((-6))
12064276
>>> id((0-5))
10022392
>>> id((-5))
10022392

इसी प्रकार तारों के लिए:

>>> x = 'abc'
>>> y = 'abc'
>>> x is y
True
>>> x = 'a little big string'
>>> y = 'a little big string'
>>> x is y
False

स्ट्रिंग कैशिंग पर अधिक जानकारी के लिए, पढ़ें: स्पेस के साथ स्ट्रिंग की तुलना करते समय ऑपरेटर अलग-अलग व्यवहार करता है


यह एक बग नहीं है। एक समानता परीक्षण नहीं है। == अपेक्षित परिणाम देगा।

इस व्यवहार के लिए तकनीकी कारण यह है कि एक पायथन कार्यान्वयन एक ही निरंतर मान के विभिन्न उदाहरणों के साथ या तो एक ही वस्तु, या विभिन्न वस्तुओं के रूप में इलाज के लिए स्वतंत्र है। आपके द्वारा उपयोग किए जाने वाले पायथन कार्यान्वयन कुछ छोटे स्थिरांक को स्मृति-बचत कारणों के लिए एक ही ऑब्जेक्ट साझा करने के लिए चुनते हैं। आप इस व्यवहार पर संस्करण या विभिन्न पायथन कार्यान्वयन के समान संस्करण होने पर भरोसा नहीं कर सकते हैं।





cpython