A Short Introduction to Python’s Coding Style
When I decided a couple of days ago to start writing about Python, I wasn’t sure what my first topic would be. Mostly because I’ve never written any article in my life before, and it’s quite intimidating. Then I thought: “Alright, I will just start with something short and simple to get my feet wet.”, so here we are.
We will have a quick look on some of the coding style guidelines for Python which will help us write a clear, consistent, and easy on the eye code.
Let’s dive right in!
Table Of Contents
- Introduction
- Naming Conventions
- To White Space or Not To White Space?
- General Guidelines
- Don’t Do Everything Yourself
Introduction
Chances are that you have already heard about PEP, but just in case you haven’t, here is the formal definition:
PEP stands for Python Enhancement Proposal. A PEP is a design document providing information to the Python community, or describing a new feature for Python or its processes or environment
There is a large list of PEPs addressing different Python related topics, but we will focus only on PEP 8 which is The guideline when it comes to Python coding style conventions. It aims to make the code more readable and consistent by defining a set of guidelines for naming conventions, usage of tabs vs spaces, maximum line length, etc.
However, keep in mind that those are not rules, sometimes it makes sense not to follow a particular guideline, check some examples here: A Foolish Consistency is the Hobgoblin of Little Minds
Naming Conventions
Let’s start by looking at a simple example. What do you think about these two functions?
def sumEvenNumbers(numbers):
even_sum = 0
for ListNumber in numbers:
if ListNumber % 2 == 0:
even_sum += ListNumber
return even_sum
def sum_odd_nums(nums):
OddSum = 0
for n in nums:
if n% 2 == 0:
OddSum+= n
return OddSum
Did it also bother you? I will take a guess and say yes (rhyming was *initially* not intentional).
The biggest problem with this example, in my opinion, is the inconsistency. We have two functions, one is in mixedCase and the other is in snake_case. The local variables defined in each of those functions also have a mixture of naming styles. Imagine having this blend of different naming conventions throughout a large project, yikes!
Now you might think: “Well, Ahmed, so what? Is that really such a big deal?” I would say yes it is, for a few reasons:
- We often read code more than we write it, so it’s important to keep it clean and easily understandable
- It’s one less thing to worry about when creating a new variable/function/class, because you already know how it should look like and you need only to come up with a descriptive name (I don’t know about you but sometimes this takes me a bit)
- Makes it easier to write static analysis or automation scripts when the naming patterns are the same everywhere
For these reasons we need to define some standards that everyone can follow.
Enter PEP 8!
It provides a guideline for the recommended naming standards for variables, classes, functions, and others. Here are some of them:
- Classes: use the CamelCase style (e.g
class InputManager
) - Functions and variables: use the snake_case style (e.g
def sum_even_numbers(numbers)
orsum_even = 0
) - Methods: same as functions, and in case it’s a non-public method use one leading underscore (e.g.
def _calculate_intermediate_sum(self)
) - Constants: use all capital letters with underscores to separate words (e.g.
MAX_WIDTH = 10
)
To White Space or Not To White Space?
Our next order of business is the usage of white spaces. This one is purely aesthetic.
To white space:
- A single space on either side of binary operators (
=
,+=
,-=
,>
,>=
,<
,<=
,==
, etc.) (e.g.sum += 5
) - A single space after the comma(s) in tuples/lists (e.g.
ages = [12, 13, 14]
,coordinates = (4, 3)
) - In functions type hints: a single space after the colon and surround the
->
with a space on either side (e.g.def sum_even(nums: List) -> int:
) - When a default value is used in combination with a type hint in a function signature, use white spaces around the
=
(e.g.def draw(scale: int = 1) -> None:
)
(I didn’t know that one before researching for this article)
Not to white space:
- Don’t add extra spaces to align operators
- Before the comma(s) in tuples/lists
- Immediately inside parentheses, brackets or braces
- Avoid trailing white spaces
Here are some final good vs bad examples:
# Good
age = 20
social_security_number = 1111
info[0] = (names[0], {'address': 'somewhere'})
heights = [180, 178, 195]
# Bad
age = 20
social_security_number = 1111
info[ 0] = ( names[ 0 ], { 'address': 'somewhere' } )
heights = [180 , 178 , 195]
General Guidelines
There is a lot of other guidelines that I would like to talk about, but to keep things short I will just leave you with a few quick-fire hints (the more detailed description can be found in the PEP 8 documentation):
- Imports should be done on separate lines
- Use space instead of tabs (except when tabs are already being used in your code base, since Python doesn’t allow mixing spaces and tabs)
- Recommended maximum line length is 79 characters for code and 72 characters for comments or docstrings
- Use 4 spaces per indentation level
Don’t Do Everything Yourself
We all need some help every once in a while, and when it comes to following the standards that we have discussed, your go-to library is autopep8
. This tool automatically formats your Python code to conform with the PEP 8 style guide, you can also specify the level of aggressiveness and whether it should ignore some rules when formatting (Rules fixed by autopep8)
To install it:
pip install autopep8
And using it is just as simple:
autopep8 --in-place --aggressive <filename>
If you are developing on Visual Studio Code, then I highly recommend using the auto formatting feature in the Python extension, where it runs autopep8
on a file when you save it.
You just need to add a few lines to your VSCode settings.json file. Here is a snippet from the settings I use:
"python.formatting.autopep8Args": [
"--max-line-length=79",
"--ignore",
"E402"
],
"editor.formatOnSave": true,
And that’s a wrap. Thank you for making it all the way to the end.
Till next time!
References
- https://peps.python.org/pep-0000/
- https://peps.python.org/pep-0001/
- https://peps.python.org/pep-0008
- https://docs.python-guide.org/writing/style
- https://pypi.org/project/autopep8/
See Also
- Check out the Doctsring Conventions: https://peps.python.org/pep-0257