2012-07-20 11 views
10

वृद्धि "अजगर आवश्यक संदर्भ" डेविड Beazley द्वारा की पृष्ठ .35 के बारे में उन्होंने पहले कहा गया है:एक स्ट्रिंग के लिए एक और चर बताए करता है इसकी प्रतिलिपि बनाने या संदर्भ गिनती

इस तरह के तारों के रूप में अपरिवर्तनीय डेटा के लिए, दुभाषिया आक्रामक कार्यक्रम के विभिन्न हिस्सों के बीच वस्तुओं को साझा करता है।

हालांकि, बाद में एक ही पृष्ठ पर, वह राज्यों

इस तरह की संख्या और तारों के रूप में अपरिवर्तनीय वस्तुओं के लिए, यह काम प्रभावी रूप से एक कॉपी बन जाती।

लेकिन क्या यह एक विरोधाभास नहीं है? एक ओर वह कह रहा है कि वे साझा किए जाते हैं, लेकिन फिर उन्होंने कहा कि उनकी प्रतिलिपि बनाई गई है।

उत्तर

5

यह प्रभावी ढंग से एक प्रति बनाता है। यह वास्तव में एक प्रतिलिपि नहीं बनाता है। दो प्रतियां और दो नाम रखने के बीच मुख्य अंतर समान मूल्य साझा करता है, बाद के मामले में, एक नाम के माध्यम से संशोधन दूसरे नाम के मूल्य को प्रभावित करते हैं। यदि मूल्य को उत्परिवर्तित नहीं किया जा सकता है, तो यह अंतर गायब हो जाता है, इसलिए अपरिवर्तनीय वस्तुओं के लिए मूल्य की प्रतिलिपि बनाई गई है या नहीं, इसके लिए व्यावहारिक परिणाम नहीं है।

कुछ कोने मामलों में जहां आप प्रतियां और विभिन्न वस्तुओं भी अपरिवर्तनीय प्रकार (जैसे, id समारोह या is ऑपरेटर का उपयोग करके) के लिए बीच का अंतर बता सकते हैं, लेकिन इन अजगर के लिए उपयोगी नहीं हैं builtin अपरिवर्तनीय प्रकार (जैसे तार और संख्या)।

+1

इस पर बहुत सारे व्यावहारिक परिणाम हैं। सामान्य रूप से प्रयुक्त 'यदि परिवर्तनीय कोई नहीं है' idiom पर विचार करें ('कोई नहीं 'एक अंतर्निहित अपरिवर्तनीय पायथन वस्तु है और यह महत्वपूर्ण है कि ऑब्जेक्ट' कोई नहीं है 'या बस' कोई नहीं 'जैसा दिखता है)। आप सैद्धांतिक रूप से एक ही स्ट्रिंग के साथ एक ही चीज कर सकते हैं जिसे विशेष के रूप में अलग किया जाता है। – mgilson

+0

वास्तव में 'अगर x कोई नहीं है' बनाम 'x == कोई नहीं' का उपयोग करने के लिए वास्तव में बहुत कम व्यावहारिक परिणाम है। वे केवल अजीब कोने के मामलों में भिन्न होंगे (उदा।, जहां 'x' एक ऑब्जेक्ट है जो अजीब' __eq__' परीक्षण को परिभाषित करता है)। तारों और संख्याओं पर 'is' का उपयोग करने के लिए भी कम व्यावहारिक आवश्यकता है। विशेष "सेट-तरफ" स्ट्रिंग्स/इनट्स के लिए 'is' पर निर्भर होने की अनुशंसा नहीं की जाती है क्योंकि यह" अलग-अलग सेटिंग "कार्यान्वयन-निर्भर है। – BrenBarn

+1

सामान्य मामले पर विचार करें जहां आप 'if x कोई नहीं है' का उपयोग करते हैं, यह जांचने के लिए कि क्या आपने कोई कीवर्ड तर्क प्राप्त किया है या नहीं। क्या होगा यदि आप मूल्य के रूप में 'कोई नहीं' स्वीकार करना चाहते हैं? आप 'SENTINAL =' 'कर सकते हैं; def foo (arg = SENTINAL); अगर (तर्क SENTINAL है): arg = [] 'उदाहरण के लिए। यह कार्यान्वयन पर निर्भर नहीं है। – mgilson

9

पायथन में एक असाइनमेंट कभी भी एक प्रतिलिपि बनाता है (यह तकनीकी रूप से संभव है यदि क्लास सदस्य के लिए असाइनमेंट उदाहरण के लिए __setattr__, गुण या वर्णनकर्ताओं का उपयोग करके फिर से परिभाषित किया गया हो)।

तो बाद

a = foo() 
b = a 

जो कुछ foo से लौटाए गए कॉपी नहीं किया गया है, और इसके बजाय आप दो चर a और b एक ही वस्तु की ओर इशारा करते है। कोई फर्क नहीं पड़ता कि वस्तु अपरिवर्तनीय है या नहीं।

अपरिवर्तनीय वस्तुओं लेकिन यह ऐसा तो नहीं है (क्योंकि आप एक चर का उपयोग कर वस्तु उत्परिवर्तित नहीं कर सकता और अगर परिवर्तन अन्य का उपयोग करते हुए दिखाई दे रहा है की जाँच करें) तो आपको लगता है के लिए स्वतंत्र हैं बताने के लिए मुश्किल है के साथ

कि वास्तव में a और b नहीं कर सकते एक दूसरे को प्रभावित करें।

कुछ अपरिवर्तनीय वस्तुओं के लिए भी अजगर के बजाय नए लोगों को बनाने की और बाद वर्ष वस्तुओं पुन: उपयोग करने

a = x + y 
b = x + y 

जहां दोनों x और y नंबर दिए गए हैं नि: शुल्क है (ताकि योग एक संख्या है और अपरिवर्तनीय है) हो सकता है कि a और b दोनों एक ही ऑब्जेक्ट पर इंगित करेंगे। ध्यान दें कि ऐसी कोई गारंटी नहीं है ... यह भी हो सकता है कि इसके बजाय वे एक ही मूल्य के साथ विभिन्न वस्तुओं को इंगित करेंगे।

याद रखने की महत्वपूर्ण बात यह है कि पायथन कभी भी एक प्रतिलिपि नहीं बनाते जब तक कि विशेष रूप से उदाहरण का उपयोग करने का निर्देश नहीं दिया जाता। copy या deepcopy।यह आश्चर्यजनक से बचने के लिए बहुत परिवर्तनीय वस्तुओं के साथ महत्वपूर्ण है।

एक आम मुहावरा आप देख सकते हैं, उदाहरण के लिए है:

class Polygon: 
    def __init__(self, pts): 
     self.pts = pts[:] 
    ... 

इस मामले self.pts = pts[:] में अंक की पूरी सरणी की एक प्रतिलिपि बनाने के लिए self.pts = pts के बजाय प्रयोग किया जाता है सुनिश्चित करने के लिए उस समय सूची नहीं बदल जाएगा अप्रत्याशित रूप से यदि ऑब्जेक्ट परिवर्तन बनाने के बाद कन्स्ट्रक्टर को पास की गई सूची में लागू किया जाता है।

+0

मुझे यह जवाब पसंद है (+1) – mgilson

संबंधित मुद्दे