jf...@ms4.hinet.net於 2018年12月28日星期五 UTC+8下午4時04分07秒寫道:
> eryk sun at 2018/12/27 UTC+8 PM 6:58:33 wrote:
> > On 12/27/18, jf...@ms4.hinet.net <jf...@ms4.hinet.net> wrote:
> > >
> > > I still don't get it. When I change it to using list comprehension, the
> > > problem is still there. (it now has no late-binding variable, right? :-)
> > >
> > >>>> class Too:
> > > ...     XS = [15, 15, 15, 15]
> > > ...     Z4 = [val for val in XS]
> > > ...     Z5 = [XS[0] for val in XS]
> > > ...
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in <module>
> > >   File "<stdin>", line 4, in Too
> > >   File "<stdin>", line 4, in <listcomp>
> > > NameError: name 'XS' is not defined
> > >
> > > The problem confuse me is that is XS a local variable of the list
> > > comprehension?
> > 
> > XS is not a local variable in the scope of either comprehension. XS is
> > local to the class statement's scope. For each comprehension, an
> > iterator for the current object referenced by XS gets instantiated
> > (early binding) and passed as an argument to the comprehension scope.
> > If we disassemble the comprehension code, we find that this iterator
> > argument has the creatively illegal name ".0". (The bytecode
> > references it by its fast-locals-array index, not its weird name.)
> > 
> > In the Z5 case, XS is a non-local variable (late binding) in the
> > loop-body expression (left-hand side) of the comprehension. That's
> > common for Python code. In every iteration of the loop, the
> > interpreter looks up the object referenced by the name "XS", which can
> > change at any time (e.g. by another thread).
> 
> In Python document 4.2.2. Resolution of names, the last paragraph:
> 
>     "...A class definition is an executable statement that may use and define 
> names. These references follow the normal rules for name resolution with an 
> exception that unbound local variables are looked up in the global namespace. 
> ...The scope of names defined in a class block is limited to the class block; 
> it does not extend to the code blocks of methods – this includes 
> comprehensions and generator expressions since they are implemented using a 
> function scope". 
> 
> These statements reflect the following difference:
> 
> >>> xy = [1,2]
> >>> [dir() for i in xy]
> [['.0', 'i'], ['.0', 'i']]
> >>> [xy[0] for i in xy]
> [1, 1]
> 
> >>> class foo():
> ...     xs = [1,2]
> ...     z4 = [dir() for i in xs]
> ...
> >>> foo().z4
> [['.0', 'i'], ['.0', 'i']]
> >>> class foo():
> ...     xs = [1,2]
> ...     z4 = [xs[0] for i in xs]
> ...
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 3, in foo
>   File "<stdin>", line 3, in <listcomp>
> NameError: name 'xs' is not defined
> >>>
> 
> and it goes further:
> 
> >>> [dir() for i in xy for j in xy]
> [['.0', 'i', 'j'], ['.0', 'i', 'j'], ['.0', 'i', 'j'], ['.0', 'i', 'j']]
> >>> class foo():
> ...     xs = [1,2]
> ...     z5 = [dir() for i in xs for j in xs]
> ...
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 3, in foo
>   File "<stdin>", line 3, in <listcomp>
> NameError: name 'xs' is not defined
> >>>
> 
> That's all I had learn so far, although not understand the design decision 
> behind it yet:-(
> 
> --Jach

Anyway, it "looks" weird. Isn't it?

>>> xs = [5,6,7,8]
>>> class foo():
...     xs = [1,2,3]
...     z4 = [xs[i] for i in xs]
...
>>> foo.z4
[6,7,8]

xs in the "for" statement referenced to class variable xs and xs[i] in the body 
referenced to the global xs with i from locals.

PS. Don't bother to reply. This is just for my own documentary:-)
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to