Originally posted on opensource.
Python 3 improved upon Python 2 in many ways; here are some of the most notable.
Python has made a name for itself in the world of programming for being easy to learn, easy to read, and reasonably easy to debug. It’s seen as a good starting language because it can usually resolve complex concepts such as data types on the programmer’s behalf. It’s considered easy to read because its syntax is simple and it enforces predictable formatting. And it’s easy to debug because not only does it catch many errors on its own, it also integrates with advanced tools like GNU Debugger (
gdb.) And that was its reputation before Python 3.
Like everything else in life, change is inevitable for programming languages. Python must iterate and develop because computers are forever improving, and people’s expectations of what a “simple” programming language does for them change over time. Additionally, other languages sometimes come up with really good ideas that get adapted into Python. Python 2.x was outrageously popular, so when Python 3 began to loom on the horizon, there was a considerable amount of anxiety mixed in with the excitement. Everyone wanted to know how Python could possibly get any better, but there was also the obligatory fear of change, the potential loss of important libraries that wouldn’t upgrade, and the uncertainty of what workload would be required to adapt existing codebases.
Years later, with Python 3 firmly established, it’s safe to say the transition went well. And what’s more, Python 3 has continued to develop and iterate, bringing in exciting enhancements that far surpass the aims of the language’s earlier iterations.
In his article series, Moshe Zadka details the 30 most significant improvements in Python 3 so far:
- Python 3.0
- Python 3.1
- Python 3.2
- Python 3.3
- Python 3.4
- Python 3.5
- Python 3.6
- Python 3.7
- Python 3.8
- Python 3.9
There have been far too many new features in Python 3 to include them all in one article, but here are five of my favorites.
1. Keyword-only arguments
In Python 3.0, keyworded arguments became significant. The idea is relatively simple: If you have a series of arguments and some of them are optional, you used to be required to pass something to account for each argument slot.
For example, say you have a function defined as
generate_widget(position, shape, color), but the
shape argument is optional. In previous versions of Python, you couldn’t skip over
shape even though it’s not required:
generate_widget(10, None, 'Blue')
As of Python 3.0, however, you can specify arguments so that any arguments not provided are set to
This is a pretty simple improvement, but it made Python feel more like other languages—in a good way. And the moment you use a function with 15 optional arguments, you very quickly learn to appreciate the change.
2. Friendly formatting
Python 3.1 introduced the unassuming (and arguably mostly insignificant) thousands-formatting feature. In short:
1024 becomes 1,024
This isn’t game-changing, it’s not essential, but it represents something important: convenience. But convenience sometimes is exactly what Python is all about.
If you look too deep into Python, you can find yourself surprisingly deep into computer science. The
functools.lru_cache feature is a great example of that, but it’s simultaneously a great example of how Python takes really advanced coding principles and makes them accessible to everybody.
functools.lru_cache, you can use a single statement (
@functools.lru_cache) in your code to enable Python to reuse the results from previously calculated values.
Python used to do filesystem paths well enough, but they were always string-based. This had the advantage of familiarity for most coders because some of the initial lessons in any basic Python course involve string manipulation. However, treating paths as strings can be cumbersome for advanced operations. The
pathlib module enables Python to treat paths as objects:
>>> text = myfile.read_text().splitlines()
>>> for line in text:
os module has many utilities for interactions with whatever operating system Python is running on. New to Python 3.5 is the
scandir function, which treats directory contents as data objects:
<posix.ScandirIterator object at 0x7fe589a8acc8>
>>> for entry in os.scandir():
Admittedly, it can be confusing to new coders to scan a directory and get a data object in return instead of a list, but dealing with objects instead of strings and other basic data types is an important lesson to learn. Features like
scandir optional keywords indicate that Python 3 has taken significant steps toward traditional language expectations and conventions.
Python’s growth has helped the language remain more relevant than ever, but for many programmers, the way Python enables them to grow as coders appeals to them the most. If you’re a new programmer just starting with Python, you can learn to do some powerful things with just a few basic lessons. Whether you want to write a utility to help you get work done, or a script to help you administer a server, or just a simple game to pass the time, Python is probably an appropriate solution.
The better you get with Python, the more of its special features you learn to use. The more features you get comfortable with, the more you’re able to do with Python. Many Python programmers have started out coding simple scripts only to accidentally find themselves professional developers within a few years.
Our Python 3 eBook aims to teach you some of the advanced features of Python 3. This isn’t for beginners. You should have a working knowledge of Python, and you should have an appetite to learn powerful new functions to make your code more elegant, more efficient, and more Pythonic.