46

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.

tshepang
  • 10,772
  • 21
  • 84
  • 127
  • 4
    Why isn't this community wiki? – S.Lott Oct 18 '10 at 00:49
  • @S.Lott: Wasn't community wiki removed? Dunno. – Nick T Oct 18 '10 at 01:02
  • 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... – Glenn Maynard Oct 18 '10 at 01:17
  • 2
    @S.Lott, @Nick T, @Glenn Maynard: [Important Change - Status completed: Users can not mark questions wiki anymore, across the network.](http://meta.stackoverflow.com/questions/67039/what-can-we-do-to-make-community-wiki-better/67192#67192) – intuited Oct 18 '10 at 01:21
  • 1
    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.) – Glenn Maynard Oct 18 '10 at 01:40
  • 1
    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 :) –  Oct 18 '10 at 02:11
  • 1
    Not closing, because the question is intelligent and there are good answers, and I'm sure this will help people. – Will May 21 '16 at 09:14
  • 2
    @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](http://stackoverflow.com/help/dont-ask). Note that closing a question does not mean that it gets deleted. – poke May 22 '16 at 14:33

14 Answers14

54

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]])
endolith
  • 21,410
  • 30
  • 114
  • 183
  • 13
    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 –  Jul 21 '13 at 23:44
  • 46
    @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. – endolith Sep 29 '13 at 12:52
  • 15
    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. – Bradley Kreider Oct 28 '14 at 18:59
  • 5
    I completely agree that alignment of operators in similar lines should be allowed – Sembei Norimaki Dec 01 '16 at 10:11
54

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.

Glenn Maynard
  • 50,887
  • 9
  • 110
  • 128
  • 43
    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. – Nick T Oct 18 '10 at 01:04
  • 40
    @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". – Glenn Maynard Oct 18 '10 at 01:12
  • 33
    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. – intuited Oct 18 '10 at 01:25
  • 10
    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. – Lyndsy Simon Dec 13 '12 at 15:38
  • 2
    @LyndsySimon: No, that's simply not the case. Well-written, perfectly natural and readable code often extends to 110-120 characters. – Glenn Maynard Dec 14 '12 at 18:49
  • 3
    @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? – Lyndsy Simon Dec 18 '12 at 18:22
  • 1
    No, I'm not; my code is perfectly readable. https://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. – Glenn Maynard Dec 19 '12 at 15:24
  • 2
    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 May 02 '13 at 06:14
  • @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. – Glenn Maynard May 02 '13 at 15:38
  • 9
    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 Aug 09 '13 at 21:37
  • 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." – Kyle Strand Aug 29 '14 at 01:05
  • 1
    -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. – IARI Aug 13 '15 at 12:54
  • 2
    Wrapping code at 80 columns results in unreadable code, so your -1 is sort of amusing. – Glenn Maynard Aug 13 '15 at 14:50
  • 1
    @GlennMaynard "90-column screens are not a reasonable development environment in 2013" Sure they are: http://sjbyrnes.com/wp-content/uploads/2012/03/spyder.jpg – endolith Jan 17 '17 at 19:13
  • @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. – Glenn Maynard Jan 25 '17 at 22:06
  • @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. – endolith Mar 16 '18 at 15:44
24

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".

endolith
  • 21,410
  • 30
  • 114
  • 183
20

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)
endolith
  • 21,410
  • 30
  • 114
  • 183
Ole Nielsen
  • 217
  • 2
  • 2
  • 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. –  Mar 23 '11 at 03:59
  • 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). – jfs Oct 18 '11 at 23:21
  • The extra spaces are ugly. I like spaces around [+-=] and none around [*/%]. I would prefer `^` to `**` but neither should have surrounding spaces! – kitsu.eb Aug 15 '12 at 20:15
  • 1
    "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 Mar 08 '13 at 19:23
  • 2
    IMHO, neither of these is readable. :) – WhyNotHugo May 02 '13 at 06:16
  • I think the reason they are both ugly is nothing to do with the spacing - you should use more variables and substitutions. – Mike Vella Aug 09 '13 at 21:40
  • 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). – paul23 Dec 17 '15 at 17:29
19

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.

Glenn Maynard
  • 50,887
  • 9
  • 110
  • 128
  • 31
    If you change any of those imports, the diff does not look so good. – tshepang Jun 30 '12 at 01:02
  • 7
    @Tshepang: It looks fine, compared to the mess of having half a page of imports at the top of a file. – Glenn Maynard Jul 05 '12 at 20:07
  • 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 Aug 15 '12 at 20:12
  • @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 Dec 13 '14 at 18:41
  • 3
    @flyingsheep for those, you do `from foo import (\n bar, \nbaz,\n)` – tshepang Dec 15 '14 at 14:45
  • 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. – Colleen Jul 20 '15 at 23:17
10

My company's style guidelines specifically call for tabs, not spaces. PEP 8 hints that spaces are preferable but we've found the opposite. I like to see code indented 4 'spaces' in VIM, a coworker prefers 8 'spaces' in Emacs. Using tabs lets us both set our editors to show the code as we prefer it.

Note that in other C-based languages, indentation is in fact merely formatting but in Python indentation is syntax, thus we feel that indentation level 2 should be represented by 2 of something (i.e. tabs) not 4 or 8 of something (i.e. spaces).

Indentation character selection is probably the original holy flame war (even before the VIM / Emacs flamewars) so I do expected to be modded to oblivion for expressing an opinion on the subject!

dotancohen
  • 26,432
  • 30
  • 122
  • 179
  • 4
    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. – Scott Ritchie Jul 25 '14 at 08:38
  • 3
    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. – dotancohen Jul 25 '14 at 10:21
  • 2
    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? – Ski Apr 01 '15 at 13:02
  • @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. – dotancohen Apr 01 '15 at 18:53
  • I prefer 32 spaces indentation :-p Especially when 2 suffice. – Mausy5043 Jun 20 '18 at 16:22
  • @Mausy5043: Gotta love those wiiiiiiiiiiiiiiiiiiiiiiiidescreen monitors! – dotancohen Jun 20 '18 at 16:31
  • 1
    @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. – StephenBoesch Mar 17 '20 at 19:51
6

My "admit violation" is about "if"

PEP8 says no multiple statement in one line, so for if we must do this :

if cond:
    actions
    ...

But when there only one action, I prefer all in one line, e.g. I prefer :

if a == 0: b = 0

than:

if a == 0:
     b = 0
Emmanuel DUMAS
  • 619
  • 8
  • 22
5

The "problem" with PEP 8 is that it treads on areas of personal preference that are subject to quite high amounts of emotion for most programmers.

For me personally, camelCase vs underscores and column alignment directives were constant issues. I also see point in lots of other responses here and sometimes I break PEP 8 intentionally because in that particular case it just "makes sense".

There was a point in my Python programming career when I simply gave up and turned to (using) PEP 8. It was relatively easy for most items, so nowadays the only major issue I still have is the column alignment. That one's just too messy to obey(though I hatefully do anyway). Anyway, as a result of my "giving up", my code is now much more readable to my colleagues - and - surprisingly: even to me (except for the column alignment thingy :p ).

I must also recognize what PEP 8 has done for python itself: between 2.x (non-compliant) and 3.x (compliant), I find it much easier to "always know" what a particular function's name will be. Python's "batteries" are sorted much nicer now.

velis
  • 6,104
  • 4
  • 40
  • 50
4

Multi-line conditionals etc.: PEP-8 explicitly says to break after a binary operator instead of before it. I'm afraid that I cannot see the appeal of that. It makes a lot more sense to me to break before the conditional, so that in wrapped/continued lines, each sub-line begins with the conditional:

if (condition1 \
        or condition2 \
        or condition3):
    do_something()

As can be seen, I also like to add an extra indent for the sublines, so that they are visually offset from the block below. PEP-8 does not say anything explicit about this (does it?), but the examples have the sub-lines lining up with the opening parentheses.

Jeet
  • 34,464
  • 5
  • 46
  • 51
  • 5
    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. – intuited Oct 18 '10 at 01:32
  • re: backslashes -- I know ... but for some reason I tend to add them! – Jeet Oct 18 '10 at 01:51
  • 10
    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 Oct 18 '10 at 01:55
  • 1
    Continuation backslashes there are reduntant. – WhyNotHugo May 02 '13 at 06:15
4

PEP 8 says:

Yes:

x = 1
y = 2
long_variable = 3

No:

x             = 1
y             = 2
long_variable = 3

i usually follow it, but i sometimes use another variant, for the sake of better readability:

x =             1
y =             2
long_variable = 3
mykhal
  • 16,760
  • 11
  • 69
  • 76
  • 3
    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. – Glenn Maynard Oct 18 '10 at 01:31
  • 7
    "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. – S.Lott Oct 18 '10 at 10:22
  • 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. – marxin Nov 12 '13 at 10:52
  • Well having all values aligned allows you to use column edit mode, found in many IDEs, and change values rather quickly. – Jorjon Feb 28 '16 at 01:24
3

I always use 4 spaces, I try to use maximum of 79 chars per line, not possible sometime. I also used imports like "import sys, os" in the past. In general I try to stick to PEP 8.

Edit: also use:

def foobar():
    """
    foobar
    """

for documentation

kelvan
  • 309
  • 2
  • 9
2

When I'm writing tiny scripts I often just use two spaces.

I always use the same pattern for docstrings:

def function():
    """
    Even if it's a single line.
    """
Engensmax
  • 65
  • 1
  • 9
Tim McNamara
  • 16,863
  • 3
  • 48
  • 77
  • 3
    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. – Glenn Maynard Oct 18 '10 at 01:00
  • 4
    Java seems to love 2 spaces, probably because you will always have to indent two levels before you actually start writing any code. – Nick T Oct 18 '10 at 01:47
  • 2
    @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. – Glenn Maynard Oct 18 '10 at 01:58
  • 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 – Lie Ryan Oct 18 '10 at 02:58
  • 2
    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. – Tim McNamara Oct 18 '10 at 03:06
  • @Tim: +1 because I believe you. – intuited Oct 18 '10 at 05:16
  • 1
    I think it's fair that people downvote if they think you are behaving badly. – tshepang Jun 30 '12 at 01:15
  • But who would think that I'm behaving badly? It's downvoting an answer to question on how people break rules. – Tim McNamara Jul 22 '12 at 03:34
  • 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](http://meta.stackexchange.com/a/104966/130885). – endolith Mar 08 '13 at 20:14
  • @tshepang _"Behaving badly"_ is this for real?? He is just stating a (reasonable!) programming preference. – StephenBoesch Mar 17 '20 at 19:48
1

python-mode.el, https://launchpad.net/python-mode

meanwhile allows customization of style:

M-x customize-variable RET py-docstring-style RET

Default value is pep-257-nn

Implemented styles are DJANGO, ONETWO, PEP-257, PEP-257-NN, SYMMETRIC, and NIL.

A value of NIL won't care about quotes position and will treat docstrings a normal string, any other value may result in one of the following docstring styles:

DJANGO:

"""
Process foo, return bar.
"""

"""
Process foo, return bar.

If processing fails throw ProcessingError.
"""

ONETWO:

"""Process foo, return bar."""

"""
Process foo, return bar.

If processing fails throw ProcessingError.

"""

PEP-257:

"""Process foo, return bar."""

"""Process foo, return bar.

If processing fails throw ProcessingError.

"""

PEP-257-NN:

"""Process foo, return bar."""

"""Process foo, return bar.

If processing fails throw ProcessingError.
"""

SYMMETRIC:

"""Process foo, return bar."""

"""
Process foo, return bar.

If processing fails throw ProcessingError.
"""
Andreas Röhler
  • 4,546
  • 11
  • 17
  • 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. – flying sheep Dec 13 '14 at 19:39
0

I use pylint, http://pypi.python.org/pypi/pylint, it is an excellent tool to try to keep your code clean and readable for you and other developers accessing your code.

I does not cover all topics you said, though, but it is very useful.

You can have reports like this one:

carlos@debian:~/src/fcl/cltools$ pylint numbertoletters.py
No config file found, using default configuration
************* Module numbertoletters
C:  1: Missing docstring
C: 56:es_numero: Missing docstring
C: 56:es_numero: Invalid name "s" (should match [a-z_][a-z0-9_]{2,30}$)
C: 56:es_numero: Invalid name "s" (should match [a-z_][a-z0-9_]{2,30}$)
C: 69:convertnumbertoletters: Empty docstring
C: 90:convertnumbertoletters: Operator not preceded by a space
    numero='%(numero)09d' % {'numero' : int(parte_entera)}
          ^
C: 92:convertnumbertoletters: Comma not followed by a space
    for i in [0,3,6]:
               ^^

W: 69:convertnumbertoletters: Unused argument 'languaje'
C:108:unidades: Empty docstring
C:108:unidades: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:108:unidades: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:112:unidades: Invalid name "u" (should match [a-z_][a-z0-9_]{2,30}$)
C:118:teens: Empty docstring
C:118:teens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:118:teens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:122:teens: Invalid name "t" (should match [a-z_][a-z0-9_]{2,30}$)
C:127:tens: Empty docstring
C:127:tens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:127:tens: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)
C:131:tens: Invalid name "t" (should match [a-z_][a-z0-9_]{2,30}$)
C:137:tercia: Empty docstring
C:141:tercia: Operator not preceded by a space
    numero='%(numero)03d' % {'numero' : int(num)}
          ^
C:143:tercia: Invalid name "a" (should match [a-z_][a-z0-9_]{2,30}$)
C:144:tercia: Invalid name "b" (should match [a-z_][a-z0-9_]{2,30}$)
C:145:tercia: Invalid name "c" (should match [a-z_][a-z0-9_]{2,30}$)
C:163:tercia: Operator not followed by a space
                resultado ='veinti '+unidades(c)
                          ^
C:165:tercia: Operator not followed by a space
        elif b >=3 and b <= 9:
               ^^
C:178:tercia: Operator not followed by a space
                resultado ='ciento '+unidades(c)
                          ^
C:192:tercia: Operator not followed by a space
                resultado ='ciento veinti '+unidades(c)
                          ^
C:204:tercia: Operator not preceded by a space
            prefix='quinientos '
                  ^
C:206:tercia: Operator not preceded by a space
            prefix='setecientos '
                  ^
C:208:tercia: Operator not preceded by a space
            prefix='novecientos '
                  ^
C:210:tercia: Operator not preceded by a space
            prefix=unidades(a)+'cientos '
                  ^
R:137:tercia: Too many return statements (23/6)
R:137:tercia: Too many branches (41/12)
R:137:tercia: Too many statements (73/50)


Report
======
141 statements analysed.

Raw metrics
-----------

+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |144    |68.25 |NC       |NC         |
+----------+-------+------+---------+-----------+
|docstring |5      |2.37  |NC       |NC         |
+----------+-------+------+---------+-----------+
|comment   |57     |27.01 |NC       |NC         |
+----------+-------+------+---------+-----------+
|empty     |5      |2.37  |NC       |NC         |
+----------+-------+------+---------+-----------+



Statistics by type
------------------

+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |1      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|method   |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|function |6      |NC         |NC         |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+



Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |NC       |NC         |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |NC       |NC         |
+-------------------------+------+---------+-----------+



Messages by category
--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |32     |NC       |NC         |
+-----------+-------+---------+-----------+
|refactor   |3      |NC       |NC         |
+-----------+-------+---------+-----------+
|warning    |1      |NC       |NC         |
+-----------+-------+---------+-----------+
|error      |0      |NC       |NC         |
+-----------+-------+---------+-----------+



Messages
--------

+-----------+------------+
|message id |occurrences |
+===========+============+
|C0103      |14          |
+-----------+------------+
|C0322      |6           |
+-----------+------------+
|C0112      |5           |
+-----------+------------+
|C0323      |4           |
+-----------+------------+
|C0111      |2           |
+-----------+------------+
|W0613      |1           |
+-----------+------------+
|R0915      |1           |
+-----------+------------+
|R0912      |1           |
+-----------+------------+
|R0911      |1           |
+-----------+------------+
|C0324      |1           |
+-----------+------------+



Global evaluation
-----------------
Your code has been rated at 7.45/10

I hope it helps.

I highly recommend the use of pylint to rate your code, and keep a standard way of programming, specially in a community of developers. =)

I hope it helps.

  • 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 :) –  Oct 18 '10 at 00:58
  • Oh, ok, I did not get the point, sorry. =) – Carlos Balderas Oct 18 '10 at 01:17