Our goal in this essay is to help you recognise and emulate high-quality Python code.
We’re going to review and contrast several development resources that might help you improve your code. The best practises and tools discussed here are useful whether you’ve been using Python for years or are just starting out.
here.
What is Code Quality?
Who wouldn’t want high-quality code? Yet, if we want to increase code quality, we must first agree on what that quality is.
Searching for “code quality definition” on Google returns several results. It turns out that different individuals assign various meanings to the phrase.
Looking at the other end of the range, at high-quality code, may help clarify the concept. With any luck, the following high-quality code may be accepted by all parties.
identifiers:
- It does what it is supposed to do.
- It does not contain defects or problems.
- It is easy to read, maintain, and extend.
These three labels are rather universally accepted, despite their simplicity. To develop these concepts further, let’s examine their significance within the field of.
software.
Why Does Code Quality Matter?
Let’s look back at those labels to remember why it’s crucial to have high-quality code. What happens if requirements aren’t met by the code will be revealed.
them.
It does
The success of every product, software or otherwise, hinges on its ability to fulfil a set of criteria. For a purpose, we develop software. If it doesn’t work in the end, it’s not very good. It’s hard to even call it low if it doesn’t satisfy the bare minimum.
quality.
It
You probably wouldn’t describe something as high-quality if it had faults or gave you headaches. If it’s terrible enough, you may even quit using it.
If we ignore software for the moment, we may assume that your vacuum is effective on standard carpet. As a result, the air is free of dirt and cat hair. The cat accidentally knocks down a plant one night, resulting in soil everywhere. It’s impossible to get rid of the mess since the vacuum breaks as you attempt to clean it.
In some cases, the vacuum performed its job, but it couldn’t manage the occasional increased volume very well. This means that it is not a high-quality vacuum.
We hope that our code will be immune to that particular issue. There is no such thing as a high-quality product if it fails under unusual circumstances and has faults that lead to unexpected results.
product.
It is
Let’s pretend a client has asked for an additional capability. We no longer have access to the original code since its creator has passed away. Their replacement now needs to decipher the code that was written before them. It is you who fit that description.
If the code is straightforward, you can quickly assess the issue and develop a remedy. It will take more time, and there’s a chance you’ll make mistakes, if the code is difficult to understand.
It’s preferable if the integration of the new feature causes little interference with the existing functionality. A new feature may cause problems for existing functionality if the code is difficult to modify.
No one like being put in a situation where they must read, maintain, or expand poor-quality code. Everyone will have to put in more effort and deal with greater stress as a result.
Dealing with poor-quality code is frustrating enough; there’s no need to subject another person to it. As a developer, you have the ability to raise the bar for the code you produce.
If you have access to a team of developers, you may begin instituting measures to improve the quality of your code as a whole. If you can count on their backing, that is. Sometimes it’s necessary to persuade others (maybe by sharing this post with them).
grinning_face_with_big_eyes).
How to Improve Python Code Quality
In our quest for high-quality code, there are a few things to keep in mind. For starters, we can’t pretend that this trip is about cold, hard facts. There are strong opinions on what constitutes good programming.
Although the aforementioned hallmarks should be universally acknowledged, the path to their actualization is up to individual interpretation. Discussions on attaining readability, maintenance, and extensibility tend to elicit the most strong opinions.
Keep in mind that there is a very subjective world of coding out there, despite the fact that this essay will strive for objectivity throughout.
Now, let’s get into the most divisive issue first: programming.
style.
Style Guides
Oh, yeah. Which is better, spaces or tabs?
We may presume that you care about maintaining some level of uniformity in your code regardless of your opinion on how whitespace should be represented.
The objective of a coding style guide is to provide uniformity in your code’s presentation. All of these modifications are purely aesthetic and do not affect the code’s functionality. Nonetheless, there are ways to avoid obvious flaws in reasoning by using certain stylistic devices.
One of the major purposes of style guidelines is to aid in the process of writing code that is simple to understand, maintain, and expand.
When it comes to Python, there is a generally acknowledged norm. The creator of the Python language contributed to its creation. Python Coding Standards, or PEP 8, gives such guidelines. Code written in Python usually adheres to this pattern. It’s an excellent jumping-off point since it’s already defined.
PEP 257 is a companion proposal to PEP 254 that defines standards for Python docstrings, which are strings used to document Python code such as modules, classes, functions, and methods. Moreover, if docstrings are consistent, tools may generate documentation from the code itself.
These standards only stipulate how code should be formatted. What about enforcing it though? And how do you find bugs and flaws in the code? This is where lint accumulates
in.
Linters
What is a Linter?
Let’s start with lint. The little flaws that always seem to get up on your clothing. Lint removal improves the quality and appearance of clothes. Your code is just like any other. Small errors, inconsistent style, and potentially harmful logic will leave your code feeling unprofessional.
It’s human nature to err, though. Do not put undue pressure on yourself to constantly be the one to seize the moment. Mistyped
The list of common programming mistakes is long: misspelt variable names, unclosed brackets, improper tabs in Python, incorrect function calls, etc. Linters are useful for spotting those trouble spots.
Additionally,
You can run linters in the background of most editors and IDEs while you work. As a result, you’ll have a setting that flags problematic sections of code before you even run it. It functions similarly to a sophisticated coding spellcheck. Just like on your preferred word processor, problems are highlighted with a red squiggly line.
In order to find lint, linters examine code for specific patterns. In general terms, we can classify these as
following:
-
Logical Lint
- Code errors
- Code with potentially unintended results
- Dangerous code patterns
-
Stylistic Lint
- Code not conforming to defined conventions
Further understanding of your code can be gained with the help of code analysis tools. While not technically “linters,” these other tools are frequently employed in tandem with linters. They, too, are invested in enhancing code quality.
Last but not least, there are automated tools to format code according to a given standard. Because of these automated tools, we can rest assured that our subpar human intellects won’t make any mistakes.
conventions.
What Are My Linter Options For Python?
You should know going in that some “linters” are really just collections of linters in a nice package. The following are a few well-known combo-linters:
Flake8: Able to pick up on both grammatical and stylistic errors. It improves upon PyFlakes’ logical lint detection by including pycodestyle’s style and complexity checks. The following are all elements that are included:
linters:
- PyFlakes
- pycodestyle (formerly pep8)
- Mccabe
Pylama is a code audit tool that includes many different linters and other code analysis tools. It melds together the
following:
- pycodestyle (formerly pep8)
- pydocstyle (formerly pep257)
- PyFlakes
- Mccabe
- Pylint
- Radon
- gjslint
The following are some linters that can be used on their own, separated into
descriptions:
Linter | Category | Description |
---|---|---|
Pylint |
Logical & Stylistic | Checks for errors, tries to enforce a coding standard, looks for code smells |
PyFlakes |
Logical | Analyzes programs and detects various errors |
pycodestyle |
Stylistic | Checks against some of the style conventions in PEP 8 |
pydocstyle |
Stylistic | Checks compliance with Python docstring conventions |
Bandit |
Logical | Analyzes code to find common security issues |
MyPy |
Logical | Checks for optionally-enforced static types |
Here is a look at the code and how it was formatted.
tools:
Tool | Category | Description |
---|---|---|
Mccabe |
Analytical |
Checks McCabe complexity |
Radon |
Analytical | Analyzes code for various metrics (lines of code, complexity, and so on) |
Black |
Formatter | Formats Python code without compromise |
Isort |
Formatter | Formats imports by sorting alphabetically and separating into sections |
Comparing Python Linters
Let’s take a closer look at the output of various linters and see what kind of errors they find. For this purpose, I used the default settings on a number of linters to examine the same code.
What follows is the code that was linted by me. Different problems with logic and style can be found in it:
The linters I used to analyse the aforementioned file are compared and their execution times are provided below for your perusal. It’s important to note that these aren’t all interchangeable, as they each serve a slightly different function. When compared to Pylint, PyFlakes is unable to detect stylistic inconsistencies.
does.
Linter | Command | Time |
---|---|---|
Pylint |
pylint code_with_lint.py | 1.16s |
PyFlakes |
pyflakes code_with_lint.py | 0.15s |
pycodestyle |
pycodestyle code_with_lint.py | 0.14s |
pydocstyle |
pydocstyle code_with_lint.py | 0.21s |
See the ensuing subsections for details on the results of each.
Pylint
The linter Pylint has been around since at least 2006 and is still actively developed and supported. That’s some tough software, if you will. Since its inception, many improvements and bug fixes have been implemented by the community.
Typical complaints levelled at Pylint are that it is slow, overly verbose by default, and requires extensive configuration to achieve the desired results. Other than the sluggishness, the other criticisms are mixed bags. Wordiness may result from an attempt at completeness. Having a wide variety of settings to tweak allows for greater customization to your individual needs.
The results of running Pylint on the lint-filled code from are shown below.
above:
No config file found, using default configuration
Take note that I've omitted unnecessary words and ellipsed over repetitions of phrases. There is a lot here to process, but
The code contains numerous lint errors.
Keep in mind that Pylint labels each error with a prefix of R, C, W, E, or F.
meaning:
-
[R]efactor for a “good practice” metric violation
-
[C]onvention for coding standard violation
-
[W]arning for stylistic problems, or minor programming issues
-
[E]rror for important programming issues (i.e. most probably bug)
-
[F]atal for errors which prevented further processing
The aforementioned items are taken right from Pylint's documentation.
.
PyFlakes
"Pyflakes makes a simple promise: it will never complain about style and will try very, very hard to never emit false positives," the authors write. As a result, Pyflakes will not flag issues like missing docstrings or inconsistently named arguments. Errors and problems with the logic of the code are the main focus.
The advantage here is rapidity. PyFlakes can be run in a fraction of the time that Pylint requires.
The result of executing on lint-filled code from
above:
The difficulty in parsing this output could be a drawback. There is no categorization or labelling of the numerous problems and mistakes. That might not be a big deal at all, depending on your intended use.
pycodestyle (formerly pep8) (formerly pep8)
For use in verifying the status of
Guidelines for Formatting Documents in PEP8
. Docstrings and naming conventions are not validated. This table organises the warnings and errors it does find.
.
The result of executing on lint-filled code from
above:
The lint is helpfully labelled by type, which is a nice feature of this output. If you don't want to follow a certain standard, you can choose to disregard certain mistakes.
pydocstyle (formerly pep257) (formerly pep257)
PEP257 is a similar tool to pycodestyle, but it checks docstrings for conformance to PEP257 docstring conventions rather than PEP8.
.
The result of executing on lint-filled code from
above:
Similar to pycodestyle, pydocstyle provides descriptive labels for each error type it discovers. Each error is preceded by a D for docstring, so there is no overlap with pycodestyle. You can find a list of those mistakes here.
.
Creating Software Free of Lint
According to the linter's report, you can modify the existing code to produce the desired result:
Those linters above report that your code is clean. Even though the reasoning is illogical on the whole, at least uniformity is maintained.
After completing the aforementioned code, we subjected it to linters. Then again, there is more than one way to test software.
quality.
When Can I Check My Code Quality?
In order to verify your code's
quality:
-
As you write it
-
When it’s checked in
-
When you’re running your tests
Regularly running lints against your code is recommended. Without proper automation and consistency, it is easy for a large team or project to lose focus and begin producing subpar code. Naturally, the process is slow. Some incoherent reasoning or perhaps code that doesn't follow the same formatting conventions as the rest of the code. This lint accumulates quickly. In the end, you may be stuck with a solution that is clumsy, difficult to read, difficult to fix, and a pain to maintain.
That won't happen if you maintain high-quality code.
often!
As You Write
While using linters during development is possible, it may take some time to set up your environment to make use of them. Typically, all that's required is a suitable plugin for your IDE or editor. Most integrated development environments (IDEs) already include linters.
The following is an overview of Python linting and its many
editors:
Before You Check In Code
You can use Git hooks to execute your linters just before committing, making Git a useful tool for code review. You can perform similar pre- and post-action scripting in other version control systems. A new piece of code that doesn't meet quality standards can be prevented from being deployed by employing these techniques.
While this may seem extreme, running all code through lint checks is a crucial step in maintaining quality. The best way to prevent lint-filled envelopes is to have the front gate automated to your code.
code.
When Running Tests
When using a continuous integration system, you can add linters right into it. If the code doesn't pass the linters, the build will be stopped.
Again, this may seem like an extreme measure, especially if the current code contains many linter errors. Some CI systems provide a safeguard against this by letting you choose to only fail the build if the number of linter errors increases as a result of the new code. In this manner, you can begin enhancing quality without having to completely rewrite your current code.