Python (2016)

CHAPTER 6: Python Versions

Before we proceed with all the coding, there is another thing that we have to clear up—the different versions of Python. Throughout this book, you will be seeing examples and suggestions that will only be effective for a specific Python version. This is especially true when we get to the optimization section towards the end. You will inevitably ask: “Which Python version should I be using?”

Here’s the (extremely) short version of things: Python 3.X is the present and the future of Python, while 2.X is the legacy.

What’s the difference?

As mentioned, the last version of the Python 2.X branch—2.7—was released back in 2010. There will be major releases after. However, Python 3.X is still being developed (very) actively, and is currently in 3.5. All of the most recent standard improvements for the library, for example, will be available only in 3.X.

However, despite the improvements of 3.X (better Unicode, turning print and exec into statements to scratch the surface), the broader ecosystem of the programming language has already amassed a huge amount of add-on quality software through its years of growth. The downside of being in bleeding-edge 3.X is the lack of backwards compatibility, therefore losing you the ability to use some of these fine software (especially those done in-house in companies).

So which version should I try to use?

For starters, you should best stick with what is on your PC—what you get with the previous chapter would be it. This will allow you to just explore the basics of Python, since you can always upgrade later. For most of you, that would probably mean starting with Python 2.7.

Now, what if you’ve already progressed beyond the basics? How do you choose whether you wish to continue with the 2.X or the 3.X branches?

As is common, the version you want to choose will greatly depend on what you want to do. You may first try getting Python 3.X and see if you can do everything with it. There will be a few downsides, which will include a slightly worse support for libraries. If you are creating software for mass distribution, be mindful that you will also need to have your users install Python 3.X. The bleeding-edge Python will also suffice if you will be writing things which will use none of the Python 2.X modules. On the upside, Python 3.X has been known to correct some quirks that are usually blockers towards learning Python.

However, there are also certain scenarios where it will be better for you to stick to legacy Python. This is primarily if you will be developing for an environment that you have no control over. These environments will usually impose their own specific versions, which will not allow you a free selection from the currently available ones. Also, you might come across the need to use a third-party utility or package which has not yet been ported to the latest branch. Sometimes, you may be able to painlessly port these packages, but this is not always the case. In these times, you should stick to Python 2.X to retain full access.

A popular module that has not yet been ported to Python 3.X (as of time of this writing) is Twisted—useful for networking application. Most of the other libraries—so long as they are actively maintained—already have people working to make them available for bleeding-edge support. However, some other libraries have other priorities—for example, Twisted focuses more on its production servers where the older Python support is more important. Supporting a brand-new version with major changes is put far back on the back burner, since the porting process is far from trivial.

Other more common modules that have already been ported to Python 3.X include Tkinter (for the creation of GUI applications), PyQt, PySide, and PyGObject (for the creation of GTK+ GUIs). Here are other packages already ported to Python 3.X:

Numpy. This is useful for number-crunching.

Django, CherryPy, Flask, and Pyramid. These are useful for web sites.

PIL (now Pillow). PIL was an image processing module which has been replaced by the Pillow fork for Python 3.X support.

Cx_Freeze. This is useful for packaging the applications complete with their dependencies.

Py2exe. This is great for packaging the application for Windows OS users.

If you find Python 3.X fun to use but are afraid of possible dependency issues, then it will be a good to do some extensive research. Note that much of the modern code written using Python 2.X should not be largely changed in Python 3.X. A sterling example will be any code written to inter-operate with GUI and web frameworks that will force aps to distinguish text and binary data.

Note as well that if you will be using an alternative Python implementation like Jython, Pyston, IronPython, and the like, you might find that there is a relative scarcity of support for Python 3.X. This might be a good consideration if you wish to choose such implementations, since you will have to think twice about performance and/or integration with other systems.

Python 2.X makes its case

As a simple Internet search will tell you, those who wish to stick around to Python 2.X are in the minority. A greater chunk of the Python community believes that the future of Python lies in its latest release. After all, it was the one that took out all the mistakes of its predecessors.

However, this is not 100% true. In fact, some of the improvements (notably the less-destructive ones) have been backported from 3.0 and 3.1 to 2.6 and 2.7 respectively. Only the following features are available exclusively on the 3.X fork (note that this is a non-exhaustive list):

●         Default Unicode strings

●         Clean separation between Unicode and bytes

●         Function annotations

●         Exception chaining

●         Keyword-only arguments syntax

●         Non-local variable declarations

●         Extended tuple unpacking

All this considered, any well-written code in 2.X can still be much like 3.X. This can be many different things. A good example is the use of the xrange function for an optimized Python 2.X code. The xrange has disappeared in Python 3.X, but is has formed the basis for the new rangeimplementation. You will see how this is applied towards the end of this book..

Bottomline? As a programmer, the best way to optimize the code is still not to pore over the strengths and weaknesses of each branch. Especially for those new to the language, the emphasis should be on the writing of good code. The tools with which you write it will only be useful if the code itself is clean.

I use Python 3.X, but there’s this library available only on 2.X. Do I change to 2.X, or should I quit on the package?

If you do not have other packages that may serve as alternatives, then you will have a few other options:

●         Port the entire library to Python 3.X.

●         If that is too hard, you can instead start off with 2.X. Then you can switch to 3.X painlessly so long as the code is good and every needed dependency has been ported.

●         Decide if that feature which requires the library is integral to your program. If not, then perhaps you could drop it.

The best resort is, of course, the first. Oftentimes, you might even find that someone is already undertaking the process of porting the library to 3.X. If that is not the case, then you can start it. While porting is not always easy, it is still a lot easier than having to write everything from scratch.

I had written code in 3.X, and now it has to be used by someone with only 2.X

For those who wish to convert code from 2.X to 3.X, a tool called 2to3 exists. Fortunately, a tool that converts the other way—3to2—also exists. Whereas the former is not always successful, converting from 3.X to 2.X is theoretically easier since the former does not have too many tough instances that the converter needs to handle. However, it is possible for code conversion to fail, especially when the source makes heavy use of features available only in the 3.X branch—such as extended tuple unpacking or function annotations.

Common code base support for Python 2.X and 3.X

Despite backward incompatibility, there is a fairly large common subset between versions 2.6+ and 3.3+. In Python 3.3, the u prefix support for the Unicode literals has been restored—this means that semantically correct code written in 2.6+ can now be source-compatible while still remaining largely “idiomatic”—a concept that will be explained later on. Handling the different names in versions 2 and 3, however, would mean that some of the things would not be imported from the same place.

In summary...

Bottom line is that while Python 3.X is more consistent, it lacks the complete support of third-party modules that 2.X enjoys. This can go on for some time, despite the great efforts of programmers. And while the 2.X family is effectively at a dead end when it comes to development, all major frameworks will still run on it. Like in 3.X, this is seen to continue for a significant amount of time. There’s also a great wealth of documentation already in place for Python 2.X, while those for 3.X are still cropping up continuously as older documents are being updated.

Some of all that talk might be confusing for you if you are a beginner to programming. Hopefully all that will be clear when you finish the book.

But then again, that is the point we are trying to make here—there are subtleties that will surely differentiate between the two branches of the same language. If you know what you’re doing, you can make an informed decision on which to use, based on all we have laid out here. But if you are just starting off, you should stick to whatever you have on your computer as you read this—there will be time to mull over versions later.

Speaking of starting off, the next chapter should send you on your merry way!