4 keys to writing modern Python

By Serdar Yegulalp

Although Python had its 30-year anniversary in 2021, the explosion of adoption, growth, and forward-thinking development associated with the language is still relatively new. Many features of Python have remained unchanged since its inception, but with every passing year, and every new edition of Python, there are new ways of doing things and new libraries that take advantage of those advances.

So, Python has its old ways and its new ways. Naturally, it makes sense to learn how to work with Python using its most modern and convenient features. Here, we’ll run down the key concepts you need to understand to write modern Python in 2024—software that uses Python’s latest and greatest idioms, concepts, and capabilities.

Type hinting in Python

Python’s recently introduced type hinting syntax allows linters and third-party code quality tools to analyze your code before runtime, and to detect possible errors before they buzz out. The more you create Python code to share with others, the more likely you (and everyone else!) will benefit from using type hints.

Each successive revision of Python rolls out more sophisticated and powerful type annotations. If you get into the habit of learning how to use type annotations in the short run, you will be better equipped to make use of each new type hinting innovation as it's introduced.

It’s important to remember that type hints are optional, not mandatory. Not every project needs them. Use type hints to make your bigger projects comprehensible, but feel free to omit them from a 50-line throwaway script. And, while type hints are not enforced at runtime, you can use Pydantic to make that possible. Many widely used Python projects use Pydantic extensively—FastAPI is one example.

Python virtual environments and package management

For simple projects and undemanding development jobs, you can often just use Python’s built-in venv tool to keep projects and their requirements separate. But recent advances in Python’s tooling give you more options:

When creating new projects that are meant to be worked on in a team environment or distributed to others (e.g., via PyPI), be sure to use the modern pyproject.toml format for your requirements and project configuration, along with the project layout used with it. You can still use the older requirements.txt file side-by-side with pyproject.toml, but the latter covers a wider range of use cases and makes your projects forward-compatible.

New Python syntax

Python’s evolution has meant many new additions to the language itself. The last few versions of Python have added useful syntactical constructions that allow for more powerful and succinct progamming. While they aren't mandatory, newer third-pary modules may use them, so they're worth getting to know at least casually.

Three recent syntax additions are especially notable.

Pattern matching

The biggest recent addition, structural pattern matching, which arrived in Python 3.10, is more than just “switch/case for Python” as it has sometimes been described. Structural pattern matching lets you make control-flow decisions based on the contents or structure of objects. In short, it's a way to match based on types or the shapes of types (a list with an int and a string, for instance) rather than values.

The ‘walrus operator’

So named for its appearance (:=), the walrus operator, added in Python 3.8, introduces assignment expressions, a way to assign a value to a variable and then apply a test to the variable in a single step. It makes for less verbose code in many common situations, such as checking a function’s return value while also preserving the results.

Positional-only parameters

A minor but useful recent addition to Python’s syntax, positional-only parameters, lets you indicate which function parameters must be specified as positional ones, never as keyword arguments. This feature is generally intended to improve the clarity and ease the future development of a codebase, goals that many of Python’s other new features also focus on.

Python testing

Writing tests for a codebase is like flossing daily: Everyone agrees it’s a good thing, few of us actually do it, and even fewer do it properly. Modern Python codebases deserve to have test suites, and the current tooling for testing makes creating test suites easier than ever.

Python has its own built-in testing framework, unittest. It isn't bad as a default, but its design and behaviors are dated. The Pytest framework has risen to prominence as a common substitute. It’s more flexible (you can declare tests in any part of your code, not just a subset) and requires writing far less boilerplate. Plus, Pytest has plenty of add-ons to expand its functionality (e.g., for testing asynchronous code).

Another important adjunct to testing is code coverage, determining how much of one’s codebase the tests actually cover. The module Coverage has you covered for this (as the name suggests) and Pytest even comes with a plug-in to work with it.

© Info World