2017-11-10 20 views
6

यहां मैं पाइथन के सूची समझ के अंदर कक्षा चर का उपयोग करने में सक्षम नहीं हूं।पायथन 3 - कक्षा चर परिभाषित नहीं किया गया है

class Student: 
    max_year = 18 
    year_choice = [i for i in range(100) if i > max_year] 

    def __init__(self, name): 
    self.name = name 
    print (self.year_choice) 

Student('Blah') 

लेकिन यह ठीक अजगर 2.

../workspace$ python student.py 
[19, 20, 21, 22, 2.... 99] 

में एक त्रुटि पायथन 3.

../workspace$ python student.py 
File "student.py", line 18, in <listcomp> 
year_choice = [i for i in range(100) if i > max_year] 
NameError: name 'max_year' is not defined 

में इस डिबगिंग से जब मैं बयान नीचे बदल काम कर रहा है लेकिन हो रही

[i for i in range(100) if i > max_year]

इस

[i for i in range(max_year)] # don't look too much into it ;) 

काम कर ठीक करने के लिए

। क्यों मैं के अंदर कक्षा चर का उपयोग करने में सक्षम नहीं हूं अगर/अन्य सूची समझ?

+0

ठीक है, यह गंभीरता से अजीब है। ;) इसके अलावा, सूची COMP के अंदर 'if' के साथ ऐसा करने के लिए कुछ भी नहीं है। यह या तो काम नहीं करता है: '[max_year-i मैं रेंज में (max_year)] ' –

+1

@py_dude उत्तर से हाँ, हम self.max_year को परिभाषित कर सकते हैं इसे इस वर्ग के वर्ग और उदाहरण के साथ साझा किया गया है। न केवल इस उदाहरण के लिए। लेकिन यहां मुझे यह जानकर उत्सुकता है कि क्यों हम क्लास वैरिएबल का उपयोग नहीं कर सकते हैं अगर/और सूची समझ में है? – ramganesh

+0

अच्छा सवाल है, लेकिन यह अभी भी एक डुप्लिकेट है ;-) –

उत्तर

4

कारण इस लाइन अजगर 2 में नहीं बल्कि अजगर 3 में

year_choice = [i for i in range(100) if i > max_year] 

काम करता है कि अजगर में 3 सूची comprehensions एक नया गुंजाइश बनाते हैं, और max_year वर्ग विशेषता है कि क्षेत्र में नहीं है। पायथन 2 में, एक सूची समझ एक नया दायरा नहीं बनाती है, यह आसपास के कोड के संदर्भ में चलता है। यह मूल रूप से प्रदर्शन कारणों से किया गया था, लेकिन बहुत से लोगों ने इसे भ्रमित कर दिया, इसलिए इसे पायथन 3 में बदल दिया गया, जिससे जनरेटर अभिव्यक्तियों के साथ सूची की समझ आती है, और सेट और निर्देशों को निर्धारित किया जाता है।

AFAIK, विधि के अंदर, कक्षा के बाहरी संदर्भ में चल रही सूची समझ के भीतर कक्षा विशेषता का उपयोग करने के लिए पाइथन 3 में कोई आसान तरीका नहीं है। आप इसे Student.max_year के साथ संदर्भित नहीं कर सकते, क्योंकि उस बिंदु पर Student कक्षा मौजूद नहीं है।

हालांकि, वास्तव में वहां कोई भी सूची समझने की कोई बात नहीं है। आप वह सूची बना सकते हैं जिसे आप अधिक कॉम्पैक्टली और अधिक कुशलतापूर्वक चाहते हैं। उदाहरण के लिए:

class Student(object): 
    max_year = 18 
    year_choice = list(range(max_year + 1, 100)) 

    def __init__(self, name): 
     self.name = name 
     print (self.year_choice) 

Student('Blah') 

उत्पादन

[19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] 

कि कोड अजगर 2 और अजगर 3. पर एक ही उत्पादन का उत्पादन

मैं

class Student(object): 
के लिए कक्षा हस्ताक्षर बदल दिया है

ताकि यह पाइथन 2 में एक नई शैली की कक्षा बनाता है (में पायथन 3 सभी कक्षाएं नई शैली हैं)।


कारण यह है कि [i for i in range(max_year)] इस प्रतिबंध के आसपास मिल सकती है कि एक इटरेटर range(max_year) जो तब अस्थायी समारोह जो सूची समझ चलाता है के लिए तर्क के रूप में पारित हो जाता है से बनाया जाता है।तो यह इस कोड के बराबर है: इस विवरण के लिए अंटी Haapala को

class Student(object): 
    max_year = 18 
    def _listcomp(iterator): 
     result = [] 
     for i in iterator: 
      result.append(i) 
     return result 

    year_choice = _listcomp(iter(range(max_year + 1, 100))) 
    del _listcomp 

    def __init__(self, name): 
     self.name = name 
     print(self.year_choice) 

Student('Blah') 

बहुत धन्यवाद।

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