Is this a bug, or is it me?

Neil Cerutti mr.cerutti at gmail.com
Thu Jan 17 16:59:06 CET 2008


On Jan 17, 2008 10:44 AM, Hrvoje Niksic <hniksic at xemacs.org> wrote:
> "Neil Cerutti" <mr.cerutti at gmail.com> writes:
>
> > You cannot access a class's class variables in it's class-statement
> > scope, since the name of the type is not bound until after the class
> > statement is completed.
>
> But they are still available as locals, so you can access them using
> their names, like this:
>
> >>> class C:
> ...   a = 1
> ...   b = 2
> ...   print a+b
> ...
> 3

Thanks! I had never tried that before. That actually solved my default
method argument problem.

> The question is, why doesn't the OP's code snippet work?  It seems
> that the generator expression can't read the surrounding locals().
> But when you change the generator expression to a list comprehension
> using a pair of [] around it, it starts working.  Compare:
>
> class C(object):
>     d = {}
>     for a in 1, 2, 3:
>         ignore = list((a, b) for b in (4, 5, 6))
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 4, in C
>   File "<stdin>", line 4, in <genexpr>
> NameError: global name 'a' is not defined
>
> with:
>
> class C(object):
>     d = {}
>     for a in 1, 2, 3:
>         ignore = [(a, b) for b in (4, 5, 6)]
>
> It seems that generator expressions and list comprehensions have
> subtly different scoping rules.  Whether this is a bug or not is a
> good question.

Generator expressions, unlike list comprehensions, have their own
scope so that they don't "leak" names to the enclosing scope. The
Python rule forbidding access to the locals of enclosing scopes is
preventing the class names from working in the generator expression.

-- 
Neil Cerutti <mr.cerutti+python at gmail.com>



More information about the Python-list mailing list