Anth's Computer Cave

Python basics: Write code that works in Python 2 and Python 3

3rd June 2015

Today I'll show you some of the differences between newer and older versions of Python, and how to write code that (hopefully) works for both.

Python 3 launched in 2010 so you would think that Python 2 would be well and truly extinct by now, but this is not the case.

Python 2 is still everywhere!

Most Linux distributions still use Python 2.7 by default, despite shipping with Python 3. Sites like Code Academy teach Python 2.7, as do some of the online university courses.

I assume it is similar to what happened with Windows XP over the years. Organizations had so much of the system reliant on XP they took almost a decade to upgrade. Some still haven't upgraded!

Likewise, many organizations and individual programmers with established projects written for Python 2.7 may have no need to port their code to Python 3. The libraries and modules they use may not have an equivalent in Python 3, or the systems the code runs on may only feature Python 2.7.

So what differences will you find between Python 2 and Python 3?

There are too many to mention here so I will cover the most common issues I encounter.

To differentiate the two versions in the images for this tutorial I am using Python 2.7 in a Raspberry Pi Linux shell (black background), and Python 3.4 in an Idle shell (white background).

The print() function

The first, and most common, difference you will find is the print() function. Both versions of Python have their own take on this.

For example, in Python 2.7 you can print with print "Hello".

Try this in Python 3, however, and things break.

The results for printing using the Python 2.7 method.

You can see that Python 3 will not print the Python 2 print call and produces a syntax error.

Python 3 requires you to place all print statements inside parentheses.

Let's try that again with print("Hello").

The method that works in both version.

You can see that both Python versions are happy with this method, so there is your first non-negotiable rule for version-compatibility.

Always use parentheses with your print statements, regardless of which Python version you use.

Joining strings inside print statements also works differently between versions.

Lets make a variable called a and assign a value of "World". Watch what happens when we join this with another string, separated by a comma.

Comma-separated arguments within print statements in version 2 and 3.

On the right you can see that Python 3 has taken our comma-separated arguments and joined them neatly together, even adding a space between them.

On the left it is not so good. Rather than join the words, Python 2 has created a tuple with the two strings instead.

We need a method that works with both versions. Let's try using an addition character instead of a comma.

The correct method for join strings on both versions of Python.

You can see that both Python versions function the same now. Notice this time I had to manually add a space after the "hello ".

So that is your next golden rule: Always join strings with addition characters rather than commas

Importing and using modules

Another issue you may encounter is using libraries and modules. Some modules may only work with either Python 2 or Python 3.

The best way around this is to do your research and try to find a suitable module that can work in both versions. In some cases that module may not exist, meaning version-compatibility may not be possible without major changes to your program.

Sometimes the module may work across versions, but use a different module name. I will use the Tkinter module as an example.

Tkinter is a Python module I use to create GUI-based programs. It can function with both version 2 and version 3 of Python, but there is one major difference.

In python 2 you import Tkinter with the command: import Tkinter.

In python 3 you import Tkinter with the command: import tkinter.

The Python2 versions has an uppercase 'T', while the Python 3 version has a lowercase 't'. It's a tiny difference, but it can kill your program before it even loads.

There are a couple of ways around this. Let's look at a standard import call.

This call is for Python 3, and it will crash a program on Python 2. By changing the first 't' to an uppercase 't' you can make it run on Python 2.

Unfortunately, importing it like this means you will also have to go through your entire code and change the spelling of every call to tkinter.

The easiest way to solve this is to use the from tkinter import * method.

You can see below that we no longer have to precede every tkinter call with 'tkinter'.

This means we only have to change the spelling of the actual import call at the top of the file.

Some people frown on importing modules in this way because it makes it difficult to tell which calls are to which modules.

Below is a compromise that keeps everyone happy.

We import the module as 't', and that is how we precede each tkinter call in the rest of our code.

If we want the program to run on Python 3 instead, we just change the spelling of the import call. The 't' preceding each call to tkinter will still work.

Let Python do it

You program's users may not wish to mess around changing the spelling of modules. Why not add some code to do it for them.

For this we'll need another module called sys. Fortunately, sys works with both versions of Python on Windows and Linux.

Type import sys.

Now type sys.version.

You can see this produces too much information for your program to use. Let's turn this info into a variable called v.

Now we can check to see if this info contains '3.4'

Bingo, we have correctly identified the system as Python 3.4.

Let's turn it into a script to add to the beginning of our program.

import sys

v = sys.version

if "2.7" in v:
    from Tkinter import *
    print("Using Tkinter for Python 2.7")
elif "3.3" in v or "3.4" in v:
    from tkinter import *
    print("Using tkinter for Python 3")

The above code is all you need to add to your Tkinter-based program to ensure it runs regardless of the Python version.

When your program starts it will create, then look inside, the v variable. If it finds the string '2.7' in v it will import Tkinter for Python 2 (With an uppercase 't'). If instead it finds '3.3' or '3.4' it will import tkinter for Python 3 (with a lowercase 't').

There are many other differences we could look at, but these are the most common issues I encounter.

I'll cover more differences in future articles.

Next article

In the next article I look at error messages and how to decipher them.

I'll also let you in on one of the most important programming tools you may already have, and show you some online resources you can use to find answers to your Python problems.



Previous: Install Python




Leave a comment on this article

Leave a comment on this article