Nel codice seguente, l'assigment mc
funziona bene in Python 2 e 3.Quali sono le regole di scoping di comprensione degli elenchi all'interno di una classe Python?
Il cc
assegnazione, che utilizza lo stesso elenco di comprensione all'interno di una classe, lavora in Python 2, ma non riesce con Python 3.
Cosa spiega questo comportamento?
ml1 = "a b c".split()
ml2 = "1 2 3".split()
mc = [ i1 + i2 for i1 in ml1 for i2 in ml2 ]
class Foo(object):
cl1 = ml1
cl2 = ml2
cc1 = [ i1 for i1 in cl1 ]
cc2 = [ i2 for i2 in cl2 ]
cc = [ i1 + i2 for i1 in cl1 for i2 in cl2 ]
print("mc = ", mc)
foo = Foo()
print("cc = ", foo.cc)
ottengo questo:
(default-3.5) snafu$ python2 /tmp/z.py
('mc = ', ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'])
('cc = ', ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'])
(default-3.5) snafu$ python3 /tmp/z.py
Traceback (most recent call last):
File "/tmp/z.py", line 5, in <module>
class Foo(object):
File "/tmp/z.py", line 11, in Foo
cc = [ i1 + i2 for i1 in cl1 for i2 in cl2 ]
File "/tmp/z.py", line 11, in <listcomp>
cc = [ i1 + i2 for i1 in cl1 for i2 in cl2 ]
NameError: name 'cl2' is not defined
Perché la classe variabile cl2
non definiti? Si noti che l'assegnazione di cc2
funziona correttamente, così come lo è cc1
. Scambiare cl1
e cl2
nella comprensione mostra che il secondo ciclo è quello che fa scattare l'eccezione, non cl2
per sé)
Versioni:.
(default-3.5) snafu$ python2 --version
Python 2.7.11+
(default-3.5) snafu$ python3 --version
Python 3.5.1+
Questo è correlato a variabili di classe vs variabili di istanza, non scope di comprensione. – TigerhawkT3
@ TigerhawkT3: In realtà, si tratta in realtà di ambito variabile nella comprensione a livello di classe. – user2357112
http://stackoverflow.com/questions/20136955/python3-nested-list-comprehension-scope –