दिलचस्प पोस्ट
सी + + अंतर्निहित रूपांतरण क्लास पुस्तकालय के साथ app.config का उपयोग करना पायथन "हर अन्य तत्व" मुहावरे "टाइमर" को लागू करने का सबसे अच्छा तरीका क्या है? MVCBuildViews सही ढंग से काम नहीं कर रहा है NSDefaultRunLoopMode बनाम NSRunLoopCommonModes डबल हटाए जाने में क्या होता है? iPhone UITextField – प्लेसहोल्डर टेक्स्ट का रंग बदलें जावा में रनिंग कमांड लाइन Express.js – app.listen बनाम server.listen घुमाए गए आयताकार में सबसे बड़ा आयत की गणना करें कैसे यूनिट परीक्षण अमूर्त वर्ग: stubs के साथ विस्तार? एक जावा ऑब्जेक्ट के गुणों को डंप करना त्रुटि: फ़ाइल बिन / डीबग / … का उपयोग नहीं कर सकता क्योंकि इसका उपयोग किसी अन्य प्रक्रिया द्वारा किया जा रहा है सी कार्यक्रम का निष्पादन समय

क्यों (0-6) है -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'> >>> 

वेब के समाधान से एकत्रित समाधान "क्यों (0-6) है -6 = गलत है?"

-5 से 256 समेकित सभी इंटिजर्स को कैपिटेड वैश्विक ऑब्जेक्ट्स के रूप में सीपीआईथॉन के साथ समान पते को बांट दिया जाता है, इस प्रकार is परीक्षा पास है।

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

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

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

पायथन स्टोर्स में पूर्णांक -5 – 256 अनुवादक में रखता है: इसमें पूर्णांक ऑब्जेक्ट्स का एक पूल है जिसमें से इन पूर्णांक लौटाए जाते हैं यही कारण है कि उन वस्तुओं समान हैं: (0-5) और -5 लेकिन नहीं (0-6) और -6 जैसा कि ये मौके पर बनाए गए हैं

यहां सीपीआईथॉन के स्रोत कोड में स्रोत है:

 #define NSMALLPOSINTS 257 #define NSMALLNEGINTS 5 static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; 

( /trunk/Objects/intobject.c स्रोत कोड देखें : / /trunk/Objects/intobject.c / /trunk/Objects/intobject.c / /trunk/Objects/intobject.c )। स्रोत कोड में निम्नलिखित टिप्पणी शामिल है:

 /* References to small integers are saved in this array so that they can be shared. The integers that are saved are those in the range -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). */ 

ऑपरेटर तो उनकी तुलना ( -5 ) के बराबर होगा क्योंकि वे एक ही वस्तु (एक ही मेमोरी स्थान) हैं, लेकिन दो अन्य नए पूर्णांक ( -6 ) भिन्न मेमोरी स्थानों पर होंगे (और फिर is True नहीं होगा) । ध्यान दें कि उपरोक्त स्रोत कोड में 257 सकारात्मक पूर्णांक के लिए है, ताकि 0 - 256 (समावेशी) हो।

( स्रोत )

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

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

ऐसा इसलिए हो रहा है क्योंकि CPython कुछ छोटे पूर्णांक और छोटे तार कैश करता है और उस ऑब्जेक्ट के प्रत्येक उदाहरण को एक समान 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 

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