Quick survey: locals in comprehensions (Python 3 only)

Chris Angelico rosuav at gmail.com
Sun Jun 24 01:18:49 EDT 2018


On Sun, Jun 24, 2018 at 3:03 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> I'd like to run a quick survey. There is no right or wrong answer, since
> this is about your EXPECTATIONS, not what Python actually does.
>
> Given this function:
>
>
> def test():
>     a = 1
>     b = 2
>     result = [value for key, value in locals().items()]
>     return result
>
>
>
>
> what would you expect the result of calling test() to be? Is that the
> result you think is most useful? In your opinion, is this a useful
> feature, a misfeature, a bug, or "whatever"?
>
> I'm only looking for answers for Python 3. (The results in Python 2 are
> genuinely weird :-)

Personally, I think it should give you [1, 2], the two values from the
function's locals. But genexps introduce some problems. Compare:

def test():
    a = 1
    b = 2
    result = list(value for key, value in locals().items())
    return result

def test_helper():
    a = 1
    b = 2
    gen = (value for key, value in locals().items())
    return gen
def test():
    return list(test_helper())

Guido has stated that he wants the list comp to be equivalent to
calling list() immediately on the genexp. And since a genexp has to be
the same thing whether you call list() on it straight away or not,
that means that all these need to behave the same way. Which, in turn,
means that the genexp needs some form of closure semantics. Thus it is
executed in an implicit nested function, and thus the list comp also
needs to be, for consistency.

So! With that in mind, I would consider bizarre behaviour of locals()
inside comprehensions to be a wart. It's not a normal thing to do, and
if it behaves weirdly, so be it. There are other things that I would
prefer to see tidied up before that.

ChrisA



More information about the Python-list mailing list