Probably the most controversial part of PEP 8 is the limit of 80 characters per line. Well, is actually 79 chars, but I’ll use 80 chars because is a round number and the way everybody referes to it.

There are a lot of companies where the standard seems to be “PEP8, except for the 80 chars line restriction”. On GitHub projects, which in general follow PEP8 (it seems to be a very strong consensus), that’s typically not found. In explicit code guidelines, the restriction could be increased (100, 120) or even removed at all. The usual reason for that is stating that we are not programming in VT100 terminals any more, and we have big, high-resolution screens. This is true, but I’ve found that that limitation, combined with the use of whitespace in Python, makes the code much more compact and readable.

It seems that, naturally, Python code tends to occupy around 35-60 characters (without indentation). Longer lines than that are much less frequent. Having suddenly a line much longer than the rest feels strange and somehow ugly. Also, having the mandatory indentation whitespace increase the line width is a good visual way of minimising the nested loops in your code and suggesting, in a subtle way, to refactor anything that is indented more than about four times.

For example, compare this:

def search(directory, file_pattern, path_match, follow_symlinks=True, output=True, colored=True): ''' Search the files matching the pattern. The files will be returned, and can be optionally printed ''' pattern = re.compile(file_pattern) results = [] for root, sub_folders, files in os.walk(directory, followlinks=follow_symlinks): # Ignore hidden directories if '/.' in root: continue # Search in files and subfolders for filename in files + sub_folders: full_filename = os.path.join(root, filename) to_match = full_filename if path_match else filename match = re.search(pattern, to_match) if match: # Split the match to be able to colorize it # prefix, matched_pattern, sufix smatch = [to_match[:match.start()], to_match[match.start(): match.end()], to_match[match.end():]] if not path_match: # Add the fullpath to the prefix smatch[0] = os.path.join(root, smatch[0]) if output: print_match(smatch, colored) results.append(full_filename) return results

with this:

def search(directory, file_pattern, path_match, follow_symlinks=True, output=True, colored=True): ''' Search the files matching the pattern. The files will be returned, and can be optionally printed ''' pattern = re.compile(file_pattern) results = [] for root, sub_folders, files in os.walk(directory, followlinks=follow_symlinks): # Ignore hidden directories if '/.' in root: continue # Search in files and subfolders for filename in files + sub_folders: full_filename = os.path.join(root, filename) to_match = full_filename if path_match else filename match = re.search(pattern, to_match) if match: # Split the match to be able to colorize it # prefix, matched_pattern, sufix smatch = [to_match[:match.start()], to_match[match.start(): match.end()], to_match[match.end():]] if not path_match: # Add the fullpath to the prefix smatch[0] = os.path.join(root, smatch[0]) if output: print_match(smatch, colored) results.append(full_filename) return results

In the first code, there is some scrolling, but even when presented in without scroll, the code looks uglier, as it does not look visually balanced. The second code seems nicer to me and I can read it easier.

Another important part is that I can display more code in the same space. There are tons of time that you need to keep an eye to different parts of the code, in the same file or in a different one. My favourite way of doing that is displaying them side-by-side in columns. Having a limit of 80 chars on the whole file, that gets nicely rendered and I don’t have to worry about lines displayed not being lines in code or configure editors. I al so makes that if I open vim for a quick fix on a terminal, I don’t have to worry much about the size. I can focus on the code.

My only problem with this is Django. While using Django you have to use a lot of this kind of calls:

ThisIsMyModel.objects.find(field1=value1, field2=value2).count()

In case of indented code, the ‘bare minimum’ of calling a model function could leave you with very few available space… I still apply the same principes, and try my best to render the code in a way that in clear and readable, but it’s more difficult that with other Python code.

So, even if the initial intention probably has little to do with all those things, I really feel that this limitation helps me writing more readable and compact code. I am sort of a “readability” integrist, in the way that I feel that readability in the code is the most important consideration by default, and should be keeping in mind at all times.

What do you think? Do you like the 80 chars limitation?

UPDATE: There is some discussion on Hacker News, in case you want to check there.

UPDATE: After a comment, I’ve released my colour scheme in GitHub. In case anyone is interested, here it is. It’s called “Jaime” just because I already had that as the name of the file.