What PEP 8 guidelines do you ignore, and which ones do you stick to?

21,305

Solution 1

The "79 characters per line" part is nonsense. Their very own example shows how unreadable code becomes when doing this:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if width == 0 and height == 0 and \
           color == 'red' and emphasis == 'strong' or \
           highlight > 100:
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

It's like try-
ing to read
a news arti-
cle written
like this.

80-column terminals havn't been a serious development environment for over a decade. When I do need to edit from a crippled 80x25 environment in a pinch, editor wrapping is a minor inconvenience; I'm not going to maim my code during normal development just to avoid that.

120 column wrapping is perfectly sensible for modern development, and I have no problem with 140. This guideline is obsolete and following it results in ugly, hard-to-read code.

Solution 2

PEP8 says to avoid "More than one space around an assignment (or other) operator to align it with another" and "never use more than one space" around math operators, but I don't follow this.

I often add "extraneous whitespace" when neighboring lines are related or very similar, but not quite the same:

search_start = (f - f_1/3) * n/fs
search_stop  = (f + f_1/3) * n/fs

 

b_lpf, a_lpf = filter(N, 2*pi*fc, 'low',  analog=True)
b_hpf, a_hpf = filter(N, 2*pi*fc, 'high', analog=True)

 

p[x >  1] =                         np.cosh(order * np.arccosh( x[x >  1]))
p[x < -1] = (1 - 2 * (order % 2)) * np.cosh(order * np.arccosh(-x[x < -1]))

 

b0 =  (1 + cos(w0))/2
b1 = -(1 + cos(w0))

Similarly, it's annoying that I get code style warnings for arrays of numbers formatted in the readable way that they are normally formatted by the library itself:

a = array([[-0.198,  0.248, -1.17 , -0.629,  1.378],
           [-1.315,  0.947, -0.736, -1.388,  0.389],
           [ 0.241, -0.98 ,  0.535,  0.951,  1.143],
           [-0.601,  1.286, -0.947,  0.037, -0.864],
           [ 0.178, -0.289, -1.037, -1.453, -0.369]])

This produces a bunch of E201 E202 E222 violations.

PEP8 would rather have it formatted it like this, apparently, because we can't ever have extra whitespace before commas or after brackets, even if it improves readability:

a = array([[-0.198, 0.248, -1.17, -0.629, 1.378],
           [-1.315, 0.947, -0.736, -1.388, 0.389],
           [0.241, -0.98, 0.535, 0.951, 1.143],
           [-0.601, 1.286, -0.947, 0.037, -0.864],
           [0.178, -0.289, -1.037, -1.453, -0.369]])

Solution 3

PEP8 says

Note that most importantly, the """ that ends a multiline docstring should be on a line by itself, and preferably preceded by a blank line, e.g.:

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""

I find this rather bizarre, since it's just "extraneous whitespace" and treats opening quotations differently from closing quotations for no obvious reason.

A rationale is given is in PEP 257:

The BDFL recommends inserting a blank line between the last paragraph in a multi-line docstring and its closing quotes, placing the closing quotes on a line by themselves. This way, Emacs' fill-paragraph command can be used on it.

Emacs, really? Everyone should do weird things to cater to the idiosyncrasies of a particular command in a particular editing tool?

I also think it's weird to put the beginning of the docstring on the same line as the quotes (not required, but recommended), while insisting that the closing quotations be on their own line. I think this is more logical, and should be used for both single line and multi-line docstrings:

def foobang(bizbaz, plotz=None):
    """
    Return a foobang

    Optional plotz says to frobnicate the bizbaz first.
    """

    if plotz is not None:
        ...

Update: The bold part has been removed and now it just says to "place the closing quotes on a line by themselves", and that the "summary line may be on the same line as the opening quotes or on the next line".

Solution 4

Standards are critical and PEP 8 is a very good style guide that I insist on. The only guideline I disagree with is the spacing around mathematical operators. For example PEP8 insists on the following spacings

Without PEP8                           With PEP8                
---------------------------------------------------------------- 
y = sqrt(x**2 + y**2)                  y = sqrt(x ** 2 + y ** 2) 
a*x**3 + b*x**2 + c*x + d              a * x ** 3 + b * x ** 2 + c * x + d 
10**(a*x + b)                          10 ** (a * x + b)  
F = V/(sqrt(g*h) + epsilon)            F = V / (sqrt(g * h) + epsilon) 
a*cos(nx/pi) + b*sin(nx/pi)            a * cos(nx / pi) + b * sin(nx / pi) 

I am trying to conform, but this is the one area where I am struggling. Do anyone else also feel that PEP8 spacing makes mathematics harder to read?

Update:

PEP8 was corrected to recommend the formatting on the left while discouraging the formatting on the right:

Yes:

i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)

No:

i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)

Solution 5

I don't agree with this:

- Imports should usually be on separate lines, e.g.:

    Yes: import os
         import sys

    No:  import sys, os

I always write simple imports together. I don't see any advantage to writing them all on separate lines: all it does is add bloat to the top of each source file, and turn something concise and easy to type into something that's borderline boilerplate, eg. something that's so verbose it starts to be tempting to copy and paste from other files.

This is instantly readable and understandable:

import sys, os, time, gc, inspect, math, doctest

It's short, easy to skim, and easy to add to. I do use multiple import statements if there are too many on one line, of course, or if I need a from import.

I also do generally keep standard library imports separate from imports of my own modules and other libraries, which agrees with the concept of grouping PEP8 recommends.

Share:
21,305

Related videos on Youtube

tshepang
Author by

tshepang

I do software development for a living and as a hobby. My favorite language is Rust, and I've used Python much in the past. My OS of choice is Debian.

Updated on August 07, 2020

Comments

  • tshepang
    tshepang almost 4 years

    Over the years, the more Python I write, the more I find myself agreeing with most of the guidelines, though I consistently and intentionally break some for my own reasons.

    I'd be curious to know what in PEP 8 (or other PEPs too maybe) people religiously stick to and why, and what people find inconvenient or inadequate.

    In my case (and at work in general), there's only a handful of things we deviate from:

    • Underscore separated lowercase names, I can see the point of it, as it will unfailingly be consistent, but we tend to use lowerCamelCase, even if it will occasionally introduce some inconsistencies (such as partially or mis-capitalized acronyms and following words, which are often down to spur-of-the-moment calls). Mostly because the near totality of the APIs we routinely use use camelCase (some upper, some lower), and because for some reason I find it easier to read, and tend to reserve underscores as separation tokens or prescribed mangling/obscuring.

    • I still can't get myself to space things out the way the PEP prescribes inside objects. new and init I tend to leave right under the class with no blank lines as I always want to read them right there with the class name and args, methods that contribute to the same scope of functionality in the class (say init, get and set of the same attrib or set of attribs) I only single-space apart, and I like three spaces between classes, and two between methods I wouldn't mentally aggregate in the map of that object. This is, again, purely for the visual impact and readability of the code. I find that very compact contents inside flow control and this kind of spacing between methods and objects consistently leads my eye exactly where I want it to go on re-readings months after the code had been parked. It also responds well to folding in my editors of choice.

    • Some things instead I stick to, that drive me nuts when I read otherwise written, is tabs instead of spaces (especially when some in-app editors we use don't really have tab replacement functionalities, contributing considerably to pollution in the code base at prototyping stage).

    • Order of things such as imports, and what imports, globals etc. It really throws me off on files that have large amounts of imports when those are mixed up or out of order.

    • Whitespaces in statements, especially when people use tabs AND try to align assignment ops across lines with different length in var names (and there seems to be no way to persuade those who do it that an excel looking piece of code is NOT neater ;) ).

    • And spacing within a control block, particularly when I see apparently random spacing within the same flow control block, and then similar amounts of spacing used within the object for methods. I'm compelled to edit those before I can even start reading the damn thing.

    So, those are mine, and the reasoning behind my "violations" of the PEP (some shared, some frowned upon by colleagues). I'd be very curious to read what other Pythonistas do and don't do in those regards.

    • user1066101
      user1066101 over 13 years
      Why isn't this community wiki?
    • Nick T
      Nick T over 13 years
      @S.Lott: Wasn't community wiki removed? Dunno.
    • Glenn Maynard
      Glenn Maynard over 13 years
      Oh, I didn't notice that. Finally, a change on this site that makes sense--I couldn't stand "community wiki" questions, and made a policy of ignoring them. People took it as permission to reverse answers that they didn't agree with, moving the position they wanted to bury into a footnote...
    • intuited
      intuited over 13 years
    • Glenn Maynard
      Glenn Maynard over 13 years
      Putting aside my personal distaste of community wiki, an observation: although answers to this question are subjective, I don't think it's meaningful to encourage editing each other's answers. These are opinions; it's not meaningful to edit another person's opinion. (I'll note, though, that I don't think these answers are valueless: people are giving their opinion based on their experiences. That's useful--at least when people give their justifications, and don't simply state their disagreement and walk off.)
    • Admin
      Admin over 13 years
      I would agree with the need for a wikification of the post if the intention was to try and reach a consensus on how to amend the PEP8 document, but that would probably be better suited to old-school, Python centric mailing lists and NG. This being more about my curiosity about inidividual choices and the reasoning behind them, the resulting wiki entry would become a large collection of weasel statements, or an aggregation of quotes that would border on the poll, neither of which I would find as interesting a read :)
    • Will
      Will almost 8 years
      Not closing, because the question is intelligent and there are good answers, and I'm sure this will help people.
    • poke
      poke almost 8 years
      @Will Just because a question may be helpful, it does not make the question objective and on-topic. This is directly asking for people’s opinions which is off-topic. Note that closing a question does not mean that it gets deleted.
  • Admin
    Admin over 13 years
    Personally I do use pylint and like it. Mostly I was curious about other programmers personal "amendments" to PEP8, and why they feel they need to bend or ignore a particular guideline :)
  • Glenn Maynard
    Glenn Maynard over 13 years
    Two-space indentation is very hard to read in any language. I'm not a stickler for four-space indents--I often use eight, largely out of long habit--but reading anything less is very uncomfortable.
  • Nick T
    Nick T over 13 years
    79 characters per line lets one fit two pages of code onto a 1680px wide screen fairly easily. That code could also be formatted much better; it's something of a strawman against 79-character lines.
  • Glenn Maynard
    Glenn Maynard over 13 years
    @Nick: I'm not going to massacre my code to accomodate your weird windowing arrangements. This code is copied directly out of the PEP-8 section on wrapping, so it's pointedly absurd to call it a "strawman".
  • Carlos Balderas
    Carlos Balderas over 13 years
    Oh, ok, I did not get the point, sorry. =)
  • intuited
    intuited over 13 years
    I was initially really opposed to the 80-character thing, but I find that if you wrap conditional sections like the one in this example in a set of parentheses, and use lisp-style indentation for it, it works out pretty well. If that's still not possible, I take it as a sign that I'm doing too much in one line, and create an intermediate variable assignment or function to handle part of the complexity. I actually forgot that it was possible to escape newlines with backlashes: I never do that.
  • Glenn Maynard
    Glenn Maynard over 13 years
    I might agree with this if you have a long list of related assignments; for example, if you're copying a list of enum values from a C header. For small quantities, as is usually the case for local variables, I'd leave out the alignment, though.
  • intuited
    intuited over 13 years
    You don't actually need the end-of-line backslashes here: a line can't end within a set of parentheses, so they continue anyway. I agree with you BTW, it seems clearer to put the conditional where it's obvious at a glance.
  • Nick T
    Nick T over 13 years
    Java seems to love 2 spaces, probably because you will always have to indent two levels before you actually start writing any code.
  • Jeet
    Jeet over 13 years
    re: backslashes -- I know ... but for some reason I tend to add them!
  • Glenn Maynard
    Glenn Maynard over 13 years
    Continuation backslashes in Python make me feel like I'm reading a big C preprocessor macro. Nobody should have to feel that way...
  • Glenn Maynard
    Glenn Maynard over 13 years
    @Nick: For all the objective reasons I dislike Java, I have a feeling I'd subjectivally hate it a lot less if it wasn't like that.
  • Lie Ryan
    Lie Ryan over 13 years
    Java requires 2 space indentation to be readable because it's an overly verbose language and anything less causes you to run out of horizontal space too soon
  • Tim McNamara
    Tim McNamara over 13 years
    I find it surprising that this has been down-voted.. the question isn't asking for recommendations. It's just asking for how people behave. The only reason to vote downwards on this answer would be if you knew that I was lying.
  • intuited
    intuited over 13 years
    @Tim: +1 because I believe you.
  • user1066101
    user1066101 over 13 years
    "better readability"? Disputable. It's just your preference. Some of us don't find it readable at all. COBOL programmers do it a lot and it doesn't help there, either.
  • Admin
    Admin about 13 years
    Agreed on. Spacing within certain operations or assignments become unreadable when used across the board, especially when dealing with precedence different from a serie like with mults/divs. I often collapse some of the additions too if it's outside a parenthesis, it just breaks the reading too much for me otherwise.
  • jfs
    jfs over 12 years
    Subjectively the left column seems to me as a line noise. At first I even thought that you mislabeled the columns due to the benefit of the right one is literally obvious to my eye (except for the last row).
  • tshepang
    tshepang almost 12 years
    If you change any of those imports, the diff does not look so good.
  • tshepang
    tshepang almost 12 years
    I think it's fair that people downvote if they think you are behaving badly.
  • Glenn Maynard
    Glenn Maynard almost 12 years
    @Tshepang: It looks fine, compared to the mess of having half a page of imports at the top of a file.
  • Tim McNamara
    Tim McNamara almost 12 years
    But who would think that I'm behaving badly? It's downvoting an answer to question on how people break rules.
  • kitsu.eb
    kitsu.eb almost 12 years
    I agree, but I try only to do this for Standard modules. import os, sys is to common to put on two lines.
  • kitsu.eb
    kitsu.eb almost 12 years
    The extra spaces are ugly. I like spaces around [+-=] and none around [*/%]. I would prefer ^ to ** but neither should have surrounding spaces!
  • Lyndsy Simon
    Lyndsy Simon over 11 years
    Generally speaking, if you've got more than 79 characters on a line, you're doing more than one thing there and should be breaking it up for readability anyhow. Still, properly descriptive names means that sometimes your lines will extend beyond the limit, and that's fine. Practicality beats purity.
  • Glenn Maynard
    Glenn Maynard over 11 years
    @LyndsySimon: No, that's simply not the case. Well-written, perfectly natural and readable code often extends to 110-120 characters.
  • Lyndsy Simon
    Lyndsy Simon over 11 years
    @GlennMaynard IMO, two of Python's greatest strengths are readability and consistency. If your lines regularly go to >79 characters, then you're negatively impacting that. There are reasons to do this that outweigh the negatives - like descriptive variable names - but they are the exception, not the rule. Do you have an example of 110-120 chars of code that you feel should be one line?
  • Glenn Maynard
    Glenn Maynard over 11 years
    No, I'm not; my code is perfectly readable. zewt.org/~glenn/wrapping.py For examples of why wrapping to 80 columns is bad, see PEP-8: it does an excellent job demonstrating how its own advice is wrong, showing how much less readable code is when it's wrapped unnaturally.
  • endolith
    endolith about 11 years
    "If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgement; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator." So I think your examples are invalid. These are good according to PEP8: x = x*2 - 1, hypot2 = x*x + y*y, c = (a+b) * (a-b), and I think they're good, too.
  • endolith
    endolith about 11 years
    I agree with the second part of your answer, but not the first part. This is why you should post multiple answers if they are independent ideas.
  • WhyNotHugo
    WhyNotHugo about 11 years
    I can fit just 90 characters (columns) of code on my desktop screen. I use NO sidebars on my laptop to fit 70. This is due to poor eyesight. Not everyone can have 120 character wide screens (my desktop is 32", but my eyesight isn't getting any better). Also, the downvote is because your "example" isn't even PEP-8 compliant. If you're gonna complain about it, and post an example, post a compliant example.
  • WhyNotHugo
    WhyNotHugo about 11 years
    Continuation backslashes there are reduntant.
  • WhyNotHugo
    WhyNotHugo about 11 years
    IMHO, neither of these is readable. :)
  • Glenn Maynard
    Glenn Maynard about 11 years
    @Hugo: #1: Don't expect me to mangle my code because your configuration is broken. 90-column screens are not a reasonable development environment in 2013 (or 2010, when this was posted). #2: My example was copied straight from PEP-8, so congratulations for admitting to a clueless downvote.
  • Admin
    Admin almost 11 years
    That drives me absolutely insane when I see it. To me it makes similar but different lines look absolutely identical. When things are deceivingly similar but not quite the same what I want amped to the max is the fact that they ARE indeed different, and not some visual homogenization that makes it harder to tell them apart. IE: I often see your last example, minus the "/2" used, and it makes it really hard to see the formulas are symmetrical. When people similarly manage to mangle reciprocals, that's when I curl up under the desk and cry :) Matter of opinion, no offence meant
  • Mike Vella
    Mike Vella almost 11 years
    This code is a perfect example of why 79 columns is a good rule, there are much better ways to implement the same logic. Usually more than 79 columns is a sign of poor design.
  • Mike Vella
    Mike Vella almost 11 years
    I think the reason they are both ugly is nothing to do with the spacing - you should use more variables and substitutions.
  • endolith
    endolith over 10 years
    @ThE_JacO: I would say that this highlights the differences by putting them next to each other, in the same way that a diff tool does. If they weren't aligned, you might notice one difference while missing another.
  • marxin
    marxin over 10 years
    For me it's extremely unreadable. I see two logically separated columns. Much better is second approach, but still, for me first example is just ..better.
  • Scott Ritchie
    Scott Ritchie almost 10 years
    The reason for the recommendation of spaces is, I believe, exactly to prevent you and your coworker from using different tab spacing amounts. You might style something that looks reasonable with 4 space indenting, but it won't look reasonable to him under 8 space indenting.
  • dotancohen
    dotancohen almost 10 years
    Thanks, Scott. Are you referring to the practice of vertically aligning = signs when multiple assignments are done on consecutive lines? If so, that can be done with spaces regardless of which characters were used for indentation.
  • Kyle Strand
    Kyle Strand over 9 years
    I do like being able to fit 2 to 3 separate source files side-by-side on one monitor, but I tend to agree with a previous coworker who said that while he appreciated the sentiment behind the 79-column restriction, it wasn't his "speed limit."
  • Bradley Kreider
    Bradley Kreider over 9 years
    It drives me insane that this is against the rules, when the goal is better readability. Code is for humans, so it should read cleanly.
  • flying sheep
    flying sheep over 9 years
    @Tshepang: well, if you add to from foo import, bar, baz, ..., you have the same problem. and nobody writes from foo import bar\nfrom foo import baz\n... and those lines will be changed more often than top-level module imports!
  • flying sheep
    flying sheep over 9 years
    i also like pep-257-nn, or symmetric. the former has the advantage that the first line is distinguished as “short description” or header, the latter that it’s, well, symmetric.
  • tshepang
    tshepang over 9 years
    @flyingsheep for those, you do from foo import (\n bar, \nbaz,\n)
  • Ski
    Ski about 9 years
    Rarely anyone is aligning = vertically in python. It is common however to align function parameters under ( , you'd have to use combination of tabs and spaces and it's just to easy to mess it up. And 8 spaces for indentation? Your colleague needs some rehabilitation. 4 spaces is accepted standard and he just needs to bear with it. What do you do if you got to pair program on someone else machine?
  • dotancohen
    dotancohen about 9 years
    @skyjur: Linus Torvalds only accepts patches with 8 spaces indentation for the Linux kernel. That's not Python, but it is feasible that someone who regularly deals with kernel code to prefer a similar environment in other contexts as well.
  • Colleen
    Colleen almost 9 years
    I actually strongly disagree with specifically @kitsu.eb 's comment. I think one line per module is the most readable and appropriate. If anything standard modules are where you would MOST want different lines.
  • IARI
    IARI almost 9 years
    -1 because I dislike the reasons given in the Answer. I believe, it should only be about how well structured and readable code is - and that is so far to a great degree independent from the developement environment.
  • Glenn Maynard
    Glenn Maynard almost 9 years
    Wrapping code at 80 columns results in unreadable code, so your -1 is sort of amusing.
  • paul23
    paul23 over 8 years
    This is a weakness in many modern day languages. Languages never seem to allow creation of extra operators to handle mathematical problems. (How I wish for the curl operator instead of having to constantly type out ugly functions, symbols are so much cleaner).
  • Jorjon
    Jorjon about 8 years
    Well having all values aligned allows you to use column edit mode, found in many IDEs, and change values rather quickly.
  • Sembei Norimaki
    Sembei Norimaki over 7 years
    I completely agree that alignment of operators in similar lines should be allowed
  • endolith
    endolith over 7 years
    @GlennMaynard "90-column screens are not a reasonable development environment in 2013" Sure they are: sjbyrnes.com/wp-content/uploads/2012/03/spyder.jpg
  • Glenn Maynard
    Glenn Maynard over 7 years
    @endolith That's not a 90-column screen, that's a normal screen that the user has configured in a weird way (and a contrived way--who has a help panel bigger than his code?), and he can't expect everybody else to contort their code style for him.
  • endolith
    endolith about 6 years
    @GlennMaynard "who has a help panel bigger than his code?" All of the thousands of people who use Spyder for scientific computing? It's the default (useful) layout.
  • Mausy5043
    Mausy5043 almost 6 years
    I prefer 32 spaces indentation :-p Especially when 2 suffice.
  • dotancohen
    dotancohen almost 6 years
    @Mausy5043: Gotta love those wiiiiiiiiiiiiiiiiiiiiiiiidescreen monitors!
  • WestCoastProjects
    WestCoastProjects about 4 years
    @tshepang "Behaving badly" is this for real?? He is just stating a (reasonable!) programming preference.
  • WestCoastProjects
    WestCoastProjects about 4 years
    I do not use pep8 at all - for many reasons. This is just one more now.
  • WestCoastProjects
    WestCoastProjects about 4 years
    @ScottRitchie "prevent you and your coworker from using different tab spacing amounts". Is that for real? let's just throw ergonomics out the door. Do you like to stand or sit while typing? Do you prefer a 15 inch laptop or two 24 inch monitors? Well let's dictate which one for you to use.
  • PatrickT
    PatrickT almost 3 years
    for your b_0, b_1 example, I would add a + sign to make the alignment with the - sign. I don't know what rule that may violate...
  • endolith
    endolith almost 3 years
    @PatrickT Yeah I do that to trick the linter sometimes. I don't think it violates any rule
  • Steven Scott
    Steven Scott over 2 years
    The main issue with 79 characters is very_long_descriptive_variable_names. In other languages these are not as much of a problem as you can write object_with_very_long_name.method_with_very_long_name(argume‌​nt_with_very_long_na‌​me, maybe_more_arguments_with_long_names) using vertical whitespace to separate things. The extra importance of whitespace in python interferes with that strategy. I like 80 columns in C++ code, but prefer wider limits in python.