この行は
year_choice = [i for i in range(100) if i > max_year]
のPython 2での作品ではなく、Pythonの3のその理由は、Python 3のリスト内包表記で新しいスコープを作成し、max_year
クラス属性は、そのスコープではないということです。 Python 2では、リスト内包は新しいスコープを作成せず、周囲のコードのコンテキストで実行されます。これはもともとパフォーマンス上の理由から行われましたが、多くの人が混乱していると感じました。したがって、Python 3ではリストの解説をジェネレータの式に合わせて変更し、解説を設定して補完しました。
AFAIKでは、メソッド内ではなく、クラスの外部コンテキストで実行されているリスト内包の内部でクラス属性にアクセスする簡単な方法はありません。その時点でStudent
クラスが存在しないため、Student.max_year
で参照することはできません。
しかし、とにかくそのリストの理解があるという点は本当にありません。よりコンパクトに、より効率的に必要なリストを作成することができます。例:このコードは、Python 2とPython 3に同じ出力を生成
[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')
出力
Iは
class Student(object):
にクラス署名を変更しました これにより、Python 2で新しいスタイルのクラスが作成されます( Python 3すべてのクラスは新しいスタイルです)。
[i for i in range(max_year)]
は、この制限を回避できるという理由は、反復子は、リストの内包表記を実行し、一時的な関数の引数として渡されrange(max_year)
から作成されていることです。したがって、次のコードと同じです。
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')
この説明については、Antti Haapalaに感謝します。
これは大変奇妙です。 ;)また、リストcompの中の 'if'とは何の関係もありません。これはうまくいきません: '[max_year-i for i in range(max_year)]' –
はい、@py_dudeから答えます。self.max_yearを定義できます。このクラスのクラスとインスタンスと共有されています。この例だけではありません。しかし、ここで私はクラス変数にアクセスできない理由を知りたいと思っています。 – ramganesh
良い質問ですが、それはまだ重複しています;-) –