[Python-ideas] Assignments in list/generator expressions

Nick Coghlan ncoghlan at gmail.com
Mon Apr 11 06:20:56 CEST 2011


On Mon, Apr 11, 2011 at 3:42 AM, Guido van Rossum <guido at python.org> wrote:
> OTOH I am personally a big fan of PEP 3150; now that the moratorium is
> lifted I hope that someone will attempt a proper implementation of it
> so we can find out all the odd corner cases (which I'm sure will be
> plentiful given that this is quite a novel thing for Python).

Not *quite* as novel as one might first think - the specific proposal
I currently have in there has its roots in the way list/set/dict
comprehensions work under the hood (in CPython, anyway). So we know
the core principle is sound, although I'm sure you're correct that
there are more corner cases still to be found in generalising the
comprehension-style copy-in/copy-out semantics appropriately.

I also thought of a somewhat decent use case for the feature, too:
"builder" code in module and class namespaces, where you need some
temporary functions, variables and loops to create a named variable,
but then have to make sure to clean up your temporary storage
locations to avoid polluting the public namespace. In the past, I'd
mostly been thinking in terms of function namespaces, and keeping
those "clean" is nowhere near as important as the situation for
classes and modules (it's quite likely someone else has brought this
up in the past, .

To lift some examples from
https://bitbucket.org/pypy/pypy/src/default/lib_pypy/disassembler.py
(which is what got me thinking along these lines)

from opcode import __all__ as _opcodes_all
__all__ = ["dis","disassemble","distb","disco"] + _opcodes_all
del _opcodes_all

Could become:

__all__ = ["dis","disassemble","distb","disco"] + opcode.__all__ given:
    import opcode

And:

def _setup():
    for opcode in opname:
        if not opcode.startswith('<'):
            class O(Opcode):
                pass
            opcode = opcode.replace('+', '_')
            O.__name__ = opcode
            globals()[opcode] = O

_setup()

Could become:

pass given: # I'll add "pass" to the list of supported statements in PEP 3150
    for opcode in opname:
        if not opcode.startswith('<'):
            class O(Opcode):
                pass
            opcode = opcode.replace('+', '_')
            O.__name__ = opcode
            globals()[opcode] = O

There's also a performance hack in there: "given:" drops you down into
a function scope, so you get the benefits of function local
performance.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list