The last version of Python 2 2.7.18 has been released, which means that Python 2 is the real EOL (end of life), and an era has finally ended.
The Python 2.0 version was released in 2000, and it has just reached its 20th anniversary (half a year later). The first version has lasted so long. Among them, version 2.7 was released after the launch of Python 3. It was released in 2010, and it has been 10 years.
In fact, Python has been born for 30 years, but the version evolution process has been very slow, and the latest version is only 3.8.2.
Comparing with the players next door who are a few years old, C++ has grown to 20, JAVA has grown to 14, PHP has grown to 7.4, and the gap is huge.
However, too frequent releases are not always a good thing. Just when Python programmers complained that their Python 2 project has not yet upgraded to version 3, some JAVA programmers are still maintaining versions 6 and 7 of the project. The bitterness of version migration, everyone laughs at each other in fifty steps.
It is almost normal for programming languages to have incompatible features across versions. In many cases, it's not that the design of the past is a bug. It's just that the programming language is also a kind of "living body". It will learn other languages and evolve itself, so it has a metabolism.
Getting rid of old incompatible versions or some outdated designs sometimes requires a long transition period. In order to facilitate programmer migration, core developers have formed some effective conventions.
Taking Python as an example, I know the following strategies:
1. DeprecationWarning prompt
When using outdated classes or methods, DeprecationWarning will appear.
For example, importing ABC (Abstract Base Classes) from the collections module is an expired usage, and the following prompt will appear:
> DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.9 it will stop working
From version 3.3, the correct usage is from collections.abc import Iterable
until version 3.9, the expiration prompt will be cancelled and an error will appear.
2. Rename the module and agree to be private
In Python, variables named with a single underscore "_" will be agreed to be private. If a private variable is defined in a module, it should not be exported to other modules in theory.
This naming method has also been extended to standard modules. For example, there was a thread
module in the very early version of Python , and later to version 1.5.1, a more convenient and easy-to-use threading
module was launched based on thread , which is the module that we are familiar with to implement multithreading.
In order to get rid of/shield the old implementation, Python renamed the thread module to _thread
and agreed to be private. This method is very flexible, ordinary programmers will not perceive its existence, but hardcore programmers can use it to achieve lower-level development. .
3. Make a deprecated prompt in the document
It has the same meaning as DeprecationWarning. The reason for listing it separately is that when I was conceiving this article, I happened to find a hint in the Python 3.8 documentation and couldn't help but share it.
The document says: The @asyncio.coroutine decorator no longer supports yield from
generator-based coroutines and needs to be explicitly written as "asyc def".
This means that version 3.8 is a dividing line for this feature, and it will enter a smooth elimination cycle.
The above three methods can be described as "removal of the old", and are made for the past version. Corresponding to them, the "welcome to the new" process is indispensable, and a future-oriented version is necessary.
In Python, some experimental features are sometimes added to the current version, and we look forward to fully implementing them in future versions. And this requires some transitional hints to programmers.
For example, in the article "Python 3.9 performance optimization: faster built-in types such as list(), dict() and range()", I introduced the "vectorcall" protocol hidden in version 3.8, which needs to be in version 3.9 It will be truly realized (and it does not rule out that it will continue to expand in the future).
In addition, there is a well-known example: the concurrent.futures
standard library introduced in version 3.2 (according to PEP-3148).
This is an asynchronous development library that integrates multithreading and multiprocess. "Concurrent" refers to concurrency, and the concept of "concurrency" can encompass the implementation of multithreading and multiprocess.
Why add a "futures" under "concurrent"? PEP-3148 points out three reasons for such a naming, the last of which is: I hope in the future to add and move existing concurrency-related libraries to the concurrent
library.
In other words, version 3.2 concurrent.futures
is an experimental design, which is concurrent
a preparation for better libraries in the future . Although the final realization in the future may be different from what was envisaged in PEP, this kind of long-term future-oriented design ideas will bring certain expectations and common beliefs to the entire community.
Well, after talking so much, it's time to wrap up.
I have never really developed or maintained a Python 2 project, so on this day that should commemorate its EOL, all I can think of is a more general topic of "removing the old and welcoming the new": how the old version features gradually After exiting, how are new version features added gradually?