Python Best Practices

Andrew Wyllie
Sep 6, 2018 · 5 min read

I don’t know, maybe ‘Best Practices’ is a bit of an overstatement. Regardless, after using python for a few years, here are some of the things I have found that work well to keep code organized, consistent and easy to maintain. My first coding jobs were as a Unix Systems Programmer so a lot of my programming bias comes from writing C code to run large networks of unix boxes and a lot of the code I write now kind of reflects that. While many modern programming languages offer “more than one way to do that”, I often prefer to use the same old tired and true patterns that everyone knows and loves (or hates). While the process of coding is an opportunity to be creative in the way a problem is solved, extending the creativity to your code by using rarely used features of a language in obtuse ways is a fool’s game. At the end of the day, the compiler takes all your fancy code and coverts it into the same byte code as the tired and true boiler plate that is easy to read and test. All of that said, my code tends to be a bit verbose and I don’t take many funky shortcuts so that the poor sucker (i.e., me) that comes along six months later who has to make some changes does not need a manual and a bottle a bourbon to wrap their head around some kind of obtuse algorithm that manipulates a data structure in some brilliantly complex and elegant way when a simple three line for loop would have sufficed.

Package Layout

This is a pretty common layout for any software package. The main features are that the top level directory contains a directory for the actual package code as well as directories for tests, docs, support files, (etc), scripts or tools (bin) as well as any configuration files for the build or test environment.

Import System — “Taming the Big Hairy Beast”

Go to StackOverflow and search for ‘python import’. You will quickly find that there are about as many different opinions on this subject as there are Python coders in the world. My requirements for code imports are:

  1. needs to be easy — setting paths is not easy and makes it a pain to move stuff around (there are a couple of exceptions to this rule when importing into a script)
  2. fully qualified names — no ‘.’ or ‘..’ and definitely not ‘…’
  3. magic — I don’t like imports that are globally imported. If I want you around I’ll do an import, otherwise, I don’t want you around.
  4. __init__.py should be empty - the purpose of the file is to show that the directory contains loadable modules
  5. Classes — python is object based, so classes are preferred but certainly not necessary. Function Programming is fine too but please try to avoid code that implements classes via functional programming — like, why?

A lot of these requirements come from writing code for AWS lambda where you need to keep the code fairly lean and clean. I learned this the hard way when I created at module to load database drivers for various databases and imported all of the drivers via the __init__.py file. What happened is that all of my code automatically included both the MongoDb and PostgreSQL drivers even if I only wanted one of them. The PostgreSQL driver is particularly huge for some reason, which meant that uploading the code to lambda was slow and that I was having trouble staying under the AWS Lambda code size limits. The limits have been relaxed recently, but there's still no reason to load code that your are not going to use. You can argue that it does not hurt anything until the day that some dependency test fails because the driver you are loading, but not using, is giving you grief. Debugging that kind of stuff sucks - try to avoid it.

PEP 8 / flake8

Why bother writing a code style guide when one is provided. The PEP8 style guide is a good starting point for code style expectations. The final say needs to be up to the team and some of the PEP8 rules can be relaxed. For example, keeping line length under 80 characters should be a recommendation, not a rule i.e., try to keep line length under 80 chars, but don’t stress if you go over by a few chars.

The simplest way to adhere to the coding style guidelines is to use flake8 and configure it to run in your editor. This will get you used to the expected code requirements and next thing you know, you are writing beautiful code and will never hear a peep from the linter.

Beyond PEP 8

flake8 is great but there are other things to consider.

Variable Names

This is always an interesting topic. The idea is to use names that self document the code. The length of the name kind of gives you an idea of what type of variable it is. For example, in Fortran, iterators were always a single character (i, j, k, etc.) which is fine as long as the variable only exists within a single block of code. Longer names (like price or material) can span blocks of code. Sometimes it’s useful to specify some attribute of the data being stored — price_cents, material_id but try to keep the names short and easy to read. Long variable names can be hard to read and follow through out the code, especially if there are a number of variations (like say your code has both price_per_part_in_cents and part_price_in_cents). While it’s admirable to have long descriptive names, it’s more important to use concise names that will not get confused with other names.

Directory, file, Class and function_names

Directories start with a capital letter e.g., Mode, Pricing

file names are all lower case and can have underscores e.g., model.py, awesome_models.py

class names start with a capital and are camel case MongoDbConnector

Unit Test Names

Unit test names have to start with test_a good convention to follow is to just use the name of the function. So if the function is called copy_file_from(), the test function would be called test_copy_file_from(). If there are more than one test for a specific function you can add a bit of extra text to the function name so test_copy_file_from_works(), test_copy_file_from_missing_file(),test_copy_file_from_invalid_filename(), etc.

Useful Tools

Virtual Environments:

Dependency management:

Documentation:

Testing:

Andrew Wyllie

Written by

VP of Engineering, ThynkHealth.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade