2016-04-17 3 views
5

इसलिए मैंने पाइथन में एक कस्टम क्लास बनाई है जो __iter__ विधि का उपयोग करके पुनरावृत्ति का समर्थन करता है। कक्षा के उदाहरण में प्रत्येक मान देने के लिए __iter__ विधि जनरेटर ऑब्जेक्ट के रूप में संरचित है, yield का उपयोग करके।मेरी कक्षा के उदाहरण पर इटर() को कॉल करना अपने वर्तमान मूल्यों का 'स्नैपशॉट' नहीं बनाता है?

मैं अगर मैं x = iter(my_instance) कुछ ऐसा कहना और फिर मेरी उदाहरण में संग्रहीत डेटा को संपादित, अगर मैं बाद में x के बाहर एक सूची का निर्माण, मैं पाएंगे कि उस सूची मूल्यों my_class वर्तमान में है कि होता है, बल्कि खोजने कर रहा हूँ जब मैंने iter() कहा था, तो उसके मानों की तुलना में।

तो मेरे सवाल इस बिंदु पर दो गुना है। सबसे पहले, क्या ऐसा होना चाहिए? यदि हां, तो ऐसा क्यों काम करता है?


ऊपर मुख्य बात है, लेकिन यदि आप वास्तव में ऊपर और परे जाना चाहते हैं, तो पढ़ना जारी रखें। अब मैं इस सवाल से पूछ रहा हूं कि मुझे इस कक्षा को विश्वविद्यालय में असाइनमेंट के रूप में बनाना है। मेरे प्रोफेसर ने एक ऐसा कार्यक्रम प्रदान किया है जो मैंने इस वर्ग पर परीक्षणों का एक गुच्छा चलाया है ताकि मुझे यह पता चल सके कि मैंने इसे पहली बार सही तरीके से किया है या नहीं।

मेरे कार्यक्रम पिछले एक है, जो मूल रूप से क्या ऊपर वर्णित है करता है को छोड़कर हर एक की जांच से गुजर रहा है। समस्या यह है कि यह सूची iter(my_object) करने के लिए एक पिछले कॉल से बनाया गया है कि समय है कि iter() उस पर बुलाया गया था पर my_object में संग्रहीत केवल मूल्यों को प्रतिबिंबित करने की उम्मीद है।

इस पर देखने के बाद मेरे आरंभिक प्रतिक्रिया है कि मेरे प्रोफेसर एक परिणाम बस list(my_object) बुला के समान प्राप्त करने का इरादा था, लेकिन मैं छात्र यहाँ हूँ, इसलिए यह संभावना बढ़ मैं बस कुछ बहुत ही अजीब में मेरी __iter__ विधि कोडित लगता है रास्ता, जो इस व्यवहार का कारण बन रहा है। या पाइथन ने हाल ही में iter() फ़ंक्शन कैसे काम किया है?


मैं के बाद से यह एक वर्ग के लिए है मेरी कोड पोस्ट करने के लिए नहीं, पसंद करते हैं, और कहा कि तकनीकी रूप से (मुझे पता है कि बेवकूफ और बेकार, खेद है) धोखा दे माना जा सकता है। हालांकि, मैं विनिर्देश को जोड़ सकता हूं, जो सही here (विशेष रूप से भाग 1, Bag वर्ग) है।

+1

आपका इटरेटर और आपकी कक्षा भंडारण के लिए समान अंतर्निहित सूची वस्तु का उपयोग कर रही है। यही कारण है कि जब आप डेटा संशोधित करते हैं तो उनमें से दोनों एक बदलाव देखेंगे। – Nayuki

+0

यदि आप इटरेटर को "फ्रीज" करना चाहते हैं, तो आप इसे स्पष्ट रूप से किसी सूची (या कुछ अन्य उपभोग डेटा प्रकार) में परिवर्तित कर सकते हैं। इटरेटर आम तौर पर आलसी होते हैं, जो बताते हैं कि आपके पास वर्णित व्यवहार क्यों है। –

+1

जब म्यूटेबल ऑब्जेक्ट्स (और आपका थैला म्यूटेबल है) पर फिर से चल रहा है, तो मानक लाइब्रेरी से इटेटर भी वही व्यवहार प्रदर्शित करेंगे: वे संशोधनों को प्रतिबिंबित करते हुए वर्तमान स्थिति में पुनरावर्तनीय पर काम करेंगे। – Cyb3rFly3r

उत्तर

1

काम कैसे आप इस

के बारे में जाना चाहिए सुनिश्चित करें कि इटरेटर समय इटरेटर को क्रियान्वित करने शुरू होता है पर थैला में उन मूल्यों का उत्पादन करने के लिए के रूप में आप एक मजबूत संकेत देने के लिए प्रकट होता है; इसलिए के दौरान बैग को उत्परिवर्तित करने से यह प्रभावित नहीं होगा कि यह किस मूल्य का उत्पादन करता है।

संकेत: इस विधि को स्थानीय जनरेटर को कॉल के रूप में लिखें, शब्दकोश की एक प्रति (सप्ताह 4 में शुक्रवार के व्याख्यान में शामिल) को पारित करें।

+0

ओह मैन, मैंने उस के दूसरे भाग को देखा, और इसका अर्थ यह था कि 'जनरेटर बनाएं' और पहली बार याद आ रही है। धन्यवाद दोस्त! – LandGod

2

के रूप में (मुझे लगता है कि) @ Cyb3rFly3r कहने की कोशिश कर रहा था, एक अस्थायी वर्ग कि इस तरह से यह मानक पुस्तकालय में कंटेनर वर्गों के लिए काम करता है के साथ अत्यधिक असंगत है करता है से अधिक पुनरावृत्ति के व्यवहार - और इसलिए हो सकता है असली दुनिया में अकेले उन आधारों पर बनाने के लिए कुछ हद तक बहस करने योग्य डिजाइन विकल्प।

यह संभवतः मुख्य कारणों में से एक का सामना करता है, जो कि इटरेटर्स की अवधारणा को पाइथन में पेश किया गया था, जो कि कंटेनर ऑब्जेक्ट्स की सामग्रियों की अलग प्रतियां बनाना था ताकि उन्हें अनावश्यक रूप से अनावश्यक किया जा सके।

वैसे भी, कि वास्तव में आप अपने __iter__() विधि में करने की आवश्यकता होगी क्या है (और क्या Peter Gibson's answer में सुझाव दे रहा है पता चला linked specification के 11 विस्तार से संकेत में है की तरह लगता है, नकल शब्दकोश कि सभी जानकारी संग्रहीत करता है Bag उदाहरण में - यह एक सादा dict आयनरी, defaultdict, या जो कुछ भी हो)।

आप चीजों को एक आंतरिक list उसकी सारी सामग्री को बनाने के बजाय पूरे होने की संभावना अधिक-जटिल डेटा की एक प्रतिलिपि बनाने के द्वारा (अतिरिक्त स्मृति प्रतिलिपि और आंतरिक रूप से इसके बारे में बार-बार दोहराना में आसानी के लिए आवश्यक कम करके) का अनुकूलन कर सकता है संरचना। ** टिप **: ऐसा करने शायद बहुत आप __repr__() विधि लागू करने के लिए तो उसके परिणामों की तरह लग रहे करने की जरूरत करने जा रहे हैं क्या करने के समान होगा:

        बैग ([ 'एक', 'सी', 'बी', 'बी', 'डी', 'डी', 'डी'])

विनिर्देश के विवरण 3 में दिखाए गए अनुसार।

चूंकि आपने कोई भी कोड पोस्ट नहीं करना चुना है, इसलिए आपको और भी मदद करना मुश्किल है।

+0

ठीक है, अब यह समझ में आता है। इसे पढ़ने के बाद और पेरटर गिब्सन ने क्या लिखा यह सब समझ में आता है। मैंने अभी सोचा कि हमें जेनरेटर कथन का उपयोग करने के लिए कहा जाना चाहिए, क्योंकि हम यह सीख रहे हैं, मुझे चीजों को कम कुशल तरीके से करने के विचार से गार्ड को पकड़ लिया गया। – LandGod

+1

आप अभी भी अपने कार्यान्वयन में जनरेटर स्टेटमेंट्स का उपयोग करके समाप्त कर सकते हैं - केवल वांछित व्यवहार प्रदान करने के लिए उपयोग की गई प्रतिलिपि या वैकल्पिक डेटा संरचना पर वे फिर से प्रयास करेंगे। – martineau

+0

हां, यह वही है जो मैंने किया है। – LandGod

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