[Python-Dev] pep8 reasoning

Barry Warsaw barry at python.org
Thu Apr 24 15:59:31 CEST 2014


On Apr 24, 2014, at 08:18 AM, Chris Withers wrote:

>I'm having a tough time persuading some people of the benefits of pep8,
>particularly when it comes to applying to an existing large code base.

First of all, the purposes of PEP 8 is not to impose mandates of style on your
colleagues. :)  Two important quotes are useful to keep in mind:

Introduction

    This document gives coding conventions for the Python code comprising the
    *standard library* in the main Python distribution.

(emphasis added)

A Foolish Consistency is the Hobgoblin of Little Minds

    A style guide is about consistency. Consistency with this style guide is
    important. Consistency within a project is more important. Consistency
    within one module or function is most important.
    [...]

    Some other good reasons to ignore a particular guideline:

    To be consistent with surrounding code that also breaks it (maybe for
    historic reasons) -- although this is also an opportunity to clean up
    someone else's mess (in true XP style).

While I personally think PEP 8 is good enough to adopt for my own projects,
and I encourage other projects to also adopt the guidelines where appropriate,
doing so is *not* always appropriate in existing source code outside the
standard library (and sometimes even within the stdlib, e.g. unittest).

>The biggest sticking point is naming, particularly as it's the one thing that
>can't necessarily be changed module by module. What were the compelling
>reasons to go from mixedCase to underscore_separated? What's considered the
>best approach for migrating from the former to the latter?

If your existing code base is already mixedCase, then there's no compelling
reason for a wholesale transition, IMO.  I work with plenty of existing
mixedCase code and it's much more jarring to see a mix of styles than it is to
see consistent mixedCase naming.  OTOH, some projects do choose to adopt PEP 8
style names over time, and they have to manage all the expected API guarantees
involved in that.

I will say this: the original preference for underscore_names in PEP 8 was
spurred by user studies some of our early non-native English speaking users
conducted many years ago.  We learned that it was more difficult for many of
them to parse mixedCase names than underscore_names.  I'm afraid I probably no
longer have references to those studies, but the difference was pronounced,
IIRC, and I think it's easy to see why.  Underscores can be scanned by the eye
as spaces, while I'd hypothesize that the brain has to do more work to read
mixedCase names.

>A couple of others that have raised some consternation; what are the
>technical reasons for this pattern being bad:
>
>if len(seq)
>if not len(seq)
>
>...or, for me, the rather ugly:
>
>if 0 != len(seq)

Well, I'd write that as `len(seq) != 0` but still, I get your point.

The rationale for this is that generic truthiness is a wider check then an
explicit value check, and EIBTI.  This really comes down to the difference
between

    if not thing:

vs

    if thing != other:

In the first case, any falsey value makes it through, while in the second
case, you're being more explicit about what you think the value of `thing` can
be.  So when semantically `thing` can be 0 or None or '', then the first test
is preferred.  When `thing` can't just be any truthy or falsey value, then a
more explicit check is preferred, otherwise some unexpected falsey value might
slip through.

It might seem less applicable to the len(seq) case, but I'd offer that that's
just an application of a more general principle.

>Likewise, these:
>
>if greeting == True:
>if greeting is True:

This one is based on the preference for identity checks when singletons are
involved, rather than equality tests.  Being composed of English words, the
latter is also more readable.  It's the same reason why you would do identity
checks against None or enum values.

>Please don't misunderstand me: I dislike the above intensely, but it's an
>emotional response based on 10-15 years of doing things the other way. I'm
>interested in arguments that don't include things like "it's pythonic" (which
>some people consider a derogatory term ;-)), or "just because", I trust that
>the stuff in pep8 was done with specific reasoning in mind, but I'm feeling
>rather useless at giving that reasoning and I'm hoping you can help :-)

I hope those explanations give you the basis for why the choices were made.
They aren't arbitrary, although folks can and do disagree.  It's much more
important that your project comes up with its own guidelines and applies them
self-consistently.  For example, I have my own small set of refinements on top
of PEP 8.  I'm not providing a link because they're a bit out of date
w.r.t. Python 3. ;)

Cheers,
-Barry


More information about the Python-Dev mailing list