As a Python programmer, what I like most about Python, is its high readability. In fact, a high level of readability is at the core of the Python language. Guido van Rossum, the inventor of the language, insists that a developer spends more time reading code than writing it. Readability counts ! and style matters because it affects readability.
Code is read much more often than it is written ~ Guido van Rossum
I. What is PEP
Python was created by Guido van Rossum, grew and evolved thanks to its community. Each improvement proposal is public and published on the Python website. They are known as Python Enhancement Proposal and each bear a number. Some are accepted, others postponed, but all are open to debate.
II. PEP 8
We will see some key points which are essential but we will not detail PEP 8. Why ? First of all because it is very well explained on the site! But also because I would like to attract your attention to a few key points, essential to know.
PEP 8 aims to define common development rules between developers. Your code follows a certain syntax and layout. You already know: indentation has the most importance in this language!
PEP 8 conventions apply as the project develops. However, it is interesting to carry out a search from time to time (before a commit for example) to detect the few crashes that could slip. The more you code, the more you will know it by heart and therefore the less you will need to look at it!
1. Code layout
Your code follows a certain syntax and layout, here are some important rules:
- A line must contain 80 characters maximum.
- Indentation must be 4 spaces.
- Add two empty lines between two high level elements, classes for example, for ergonomic reasons.
- Separate each function with an empty line.
A docstring is a set of words that documents a piece of code. It begins with three opening quotes, the comment you want to make, then three closing quotes.
According to PEP 8, each part of your code should contain a Docstring:
- all public modules
- all functions
- all the classes and all the methods of these classes
The import of a library must be quick to detect. It is also important to clearly differentiate the source of the libraries: standard, external or local.
- Imports are to be placed at the start of a script.
- They precede the Docstrings.
- One line per library.
- The import must follow the following order: Standard libraries, third-party libraries and local imports. Skip a line between each of these blocks.
3. Whitespace in the instructions
The spaces follow the Anglo-Saxon syntax. More generally, it focuses on readability while removing whitespaces.
- no space before : but one after. Example:
- Operators: a space before and an after. Example:
i = 1 + 1
- No spaces before and after an = sign when you assign the default value for the parameter of a function. Example:
def elephant(trunk=True, legs=4)
4. Naming conventions
This is an essential point, here are the highlights :
- Modules: short name, all lowercase, underscore if necessary.
- packages: short name, all lowercase, underscores strongly not recommended.
- classes: capital letter at the beginning of the word.
- exceptions: similar to classes but with an Error at the end.
- functions: lowercase and underscore:
- methods: lowercase, underscore and self as the first parameter:
- variables: identical to functions.
- constants: all in capital letters with underscores if necessary.
- private: preceded by two underscores:
- protected: preceded by a dash:
III. ZEN of Python
In the previous section you discovered PEP 8 which is the style guide for writing quality code in Python. This PEP intimately linked to PEP 20, these are 19 verses written by Tim Peters and reflecting the philosophy of Python. You can think of them as guides to conduct that help you write better code and understand the mindset of language:
import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
Nothing like practice to understand what these aphorisms imply!
Here are the first two:
Beautiful is better than ugly
Explicit is better than implicit
here are examples using aphorisms, discover them all here
Am I supposed to review my code from top to bottom manually or there is a tool can do it for me ?
Yes ! You are supposed to review your code, but doing it manually, it's tedious and time consuming. Several code analysis solutions exist to make your work easier ! Let me introduce you to one: Pylint.
Pylint is a Python static code analysis tool which analyzes the code according to PEP 8 standards, looks for programming errors, helps enforcing a coding standard, sniffs for code smells and offers simple refactoring suggestions.
It's highly configurable, having special pragmas to control its errors and warnings from within your code, as well as from an extensive configuration file. It is also possible to write your own plugins for adding your own checks or for extending pylint in one way or another.
How to do it ?
Start by installing Pylint:
pip install pylint
When Pylint is installed, start the analysis by typing:
Here is the result of his analysis:
Ouch! -5.00 / 10 ... We have a bad quality code here ! Indeed, there is a missing final newline, no Docstring and unused import. Let's fix that and relaunch Pylint.
oh finally !
PEP 8 is a very important set of rules but which can be broken in certain specific contexts. Just remember that it guarantees a readable and quality code that improves collaboration between developers.
Okay ! so far so good, but I want to force my commits to respect PEP8 before any git-commit?
Yes of course !
At any startup, commits are pushed frequently through various projects and merge requests are created daily, now can you imagine reviewing all this ?! what about maintaining code quality standards ? All of this presents a huge challenge for developers.
Making developers correct their code format or telling them to make changes to follow PEP 8 standards is frustrating* (as our CTO, Mohammed aboulliate says).
You can also do this with Pylint ! I decided to show you other tools, so that we don't limit ourselves with just one tool
flake8 is a command-line utility for enforcing style consistency with respect to PEP 8 across Python projects and it will also run third-party extensions if they are found and installed. In the other hand, black is a python code formatter. We will also need pre-commit python framework which is a multi-language package manager for pre-commit hooks. You specify a list of hooks you want and pre-commit manages the installation and execution of any hook written in any language before every commit.
how it works ?
Before we commit our staged python files, black will format our code and flake8 will check compliance to PEP8. If everything passes, the commit is made. If not, then we must perform the necessary edits and commit again.
How to do it ?
1- start by installing pre-commit:
pip install pre-commit
.pre-commit-config.yaml with the hooks you want to include.
4- Execute pre-commit install to install git hooks in your .git/ directory.
The YAML file configures the sources where the hooks will be taken from. We need to define where to source black & flake8 and we need to specify their ids using few lines of code.
Below is a sample
repos: - repo: https://github.com/ambv/black rev: stable hooks: - id: black language_version: python3.6 - repo: https://gitlab.com/pycqa/flake8 rev: 3.7.9 hooks: - id: flake8
Now that we have a pre-commit framework set-up with black and flake8, let’s see it's gonna perform :
Now as you try to commit your code it will show you all coding style issues. You will only be able to commit until code is pep8 compliant.
Wait a moment ! should I use Pylint or flake8?
When comparing Pylint vs flake8, Developers recommend Pylint for most people. Pylint is ranked 1st while flake8 is ranked 2nd. The most important reason people chose Pylint is:
Pylint gives very detailed reports of your code. It also provides detailed statistics about the results. Data for the previous and current code execution is also available with the difference, allowing you to easily see the progress that you have made. See more here
Final word !
Do not let these verses prevent you of learning Python. But, keep in mind that is easier to learn something right the first time compared to breaking a bad habit.