2017-11-10 123 views
6

Burada bir Python'un liste anlaşmasında liste sınıf değişkenine erişemiyorum.Python 3 - Sınıf değişkeni tanımlanmadı

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') 

Ama deyimi altında değiştikten sonra bu hata ayıklama gelen Python 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 

bir hata Python 2.

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

ince çalışma Fakat gidiyor

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

Bu

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

çalışma cezası

. Neden içinde sınıf değişkenine erişemiyorum/else liste anlaşması?

+0

Tamam, bu çok garip. ;) Ayrıca, liste comp içinde 'if' ile ilgisi yoktur. Bu, aşağıdakileri yapmaz: '[max_year-i aralıkta (max_year)]' –

+1

Evet @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ sadece bu örnek için değil. Ama burada/sınıf listesi anlama içinde neden sınıf değişkenine erişemediğimizi merak ediyorum. – ramganesh

+0

İyi bir soru ama yine de bir çift ;-) –

cevap

4

bu hat Python 2'de ancak Python 3'te

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

eserler Python 3 liste comprehensions Yeni kapsam oluşturmak ve max_year sınıf niteliği o kapsamda olmadığıdır nedeni. Python 2'de liste kavraması yeni bir kapsam oluşturmaz, çevreleyen kod bağlamında çalışır. Bu başlangıçta performans nedenleriyle yapıldı, ama birçok kişi kafa karıştırıcı buldu, bu yüzden Python 3'te değiştirildi, liste anlamalarını jeneratör ifadeleriyle uyumlu hale getirdi ve anlaşmaları belirledi ve belirledi.

AFAIK, Python 3'te, bir yöntemin içinde değil, bir sınıfın dış bağlamında çalışan liste kavrama içindeki bir sınıf özelliğine erişmek için basit bir yol yoktur. Bu noktada, Student sınıfı bulunmadığından, Student.max_year ile başvuruda bulunamazsınız. Bununla birlikte, yine de bu listeyi anlama konusunda hiçbir anlam ifade etmemektedir. İstediğiniz listeyi daha kompakt ve daha verimli bir şekilde oluşturabilirsiniz. Örneğin: Bu kod Python 2 ve Python 3. aynı çıktıyı üretir

[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] 

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') 

çıkış

Ben

class Student(object): 
sınıfı imza değiştirdik

, böylece Python 2'de yeni stil sınıfı yaratır Python 3 tüm sınıflar yeni tarzdır).


[i for i in range(max_year)] Bu kısıtlama alabilirsiniz nedeni bir yineleyici sonra liste anlama çalışır geçici işleve argüman olarak geçirilir range(max_year) oluşturulur olmasıdır.Yani bu kodun eşdeğeri:

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') 

Bu açıklama için Antti Haapala'ya çok teşekkürler.