[Python-ideas] A comprehension scope issue in PEP 572

Steven D'Aprano steve at pearwood.info
Sat May 12 04:56:27 EDT 2018

There's a lot of things in Brendan's email which I disagree with but 
will skip to avoid dragging this out even further. But there's one point 
in particular which I think is important to comment on.

On Thu, May 10, 2018 at 11:23:00AM -0700, Brendan Barnwell wrote:

> One of the great things about Python's design is that 
> it doesn't just make it easy for us to write good code, but in many ways 
> makes it difficult for us to write bad code.

I don't think this concept survives even a cursory look at the language. 
Make it difficult to write bad code? Let's see now:

Anyone who have been caught by the "mutual default" gotcha will surely 

def func(arg, x=[]):

And the closures-are-shared gotcha:

py> addone, addtwo, addthree = [lambda x: x + i for i in (1, 2, 3)]
py> addone(100)
py> addtwo(100)

We have no enforced encapsulation, no "private" or "protected" state for 
classes. Every single pure-Python class is 100% open for modification, 
both by subclasses and by direct monkey-patching of the class. The term 
"monkey-patch" was, if Wikipedia is to be believed, invented by the 
Python community, long before Ruby took to it as a life-style.

We have no compile-time type checks to tell us off if we use the same 
variable as a string, a list, an int, a float and a dict all in the one 
function. The compiler won't warn us if we assign to something which 
ought to be constant. We can reach into other modules' namespaces and 
mess with their variables, even replacing builtins.

Far from making it *hard* to do bad things, Python makes it *easy*. 

And that's how we love it!

Consenting adults applies. We trust that code is not going to abuse 
these features, we trust that people aren't generally going to write 
list comps nested six levels deep, or dig deep into our module and 
monkey-patch our functions:

    import some_module
    some_module.function.__defaults__ = (123,)  # Yes, this works.

As a community, we use these powers wisely. We don't make a habit of 
shooting ourselves in the foot. We don't write impenetrable forests of 
nested comprehensions inside lambdas or stack ternary-if expressions six 
deep, or write meta-metaclasses.

Binding expressions can be abused. But they have good uses too. I trust 
the Python community will use this for the good uses, and not change the 
character of the language.

Just as the character of the language was not ruined by comprehensions, 
ternary-if or decorators.


More information about the Python-ideas mailing list