Python 2 & 3 Compatible print and input

The title of this tutorial is a bit misleading, but I will explain that.

Note: This tutorial uses methods from my other tutorial, What Python Version is This? It may be best to read that tutorial first.

As you may know, there is lot of incompatible code between Python 2 and 3. Some of the most obvious incompatible changes in Python 3 that will break Python 2 code (and vice-versa) are the conversion of the print statement (print) to the print function (print()), and the updating of raw_input() to input().

If you at any point want to make a Python 2 and 3 compatible version of your script, you need to find a way to bridge these two major changes, but how do you bridge them? Read on to find out how.

While all code is Python 2 and 3 compatible, any Exceptions are from Python 3.3+.

The printing Press

There are three different ways you can solve this issue. I will list them in order from “Ideal fix” to “It will do”. Do note this is not an exhaustive list of methods, there are other ways to do this. I am just listing the three most popular.

  1. You can use the __future__ module using the syntax from __future__ import print_function to bring the full-fledged Python 3 print() function to your Python 2 script.

    This import brings the entire Python 3 print function to Python 2, including the new sep=" ", end="\n", and file=f parameters. The entire import is ignored in Python 3, so your interpreter will not run that line. This is the best method in my eyes. Although you are not going to be mixing the statement and function in the same script, you get to benefit from the superior internal workings and train you for the inevitable switch to a Python 3 only world. This method is also the most widely recommended method by multiple sites and companies, such as Canonical Ltd. (the maintainers of Ubuntu Linux) on their Python 3 page.

  2. Although Python 3 changed the way you print text, it did not change the destination of the text; it all goes to sys.stdout, AKA the console window. This method only adds one new line to you code (assuming you are not already importing sys). Using this instead of print(), you can a send your text directly to the console, like so:

    There are a few differences between using print() and sys.stdout.write, though. First, all new lines must be explicitly stated; it doesn’t write them for you (like the print statement). Second, everything must be a string, so boolean (True, False) and float/integer values must be converted to a string before it can be displayed, or you’ll hit an error. However, you simply need to wrap your text in a str() to fix that.

  3. Finally, you can use the faux print function in Python 2 added specifically to help port code from 2 to 3. I advise to stay away from this at all costs, unless you are 120% sure nobody will run attempt to your script on a really old version of Python. In addition, it is not even the full print function. It acts and is interpreted exactly like the statement, but uses parentheses to avoid a SyntaxError on Py3. It also incorrectly interprets the .format() method, creating an AttributeError on 3.As I said, try to avoid this method at all costs.

So, you want my input?

Like print, input has a few solutions, but with on out of the scope of this tutorial, I will example the easier solution. Since raw_input() was removed in Python 3 and input() took its place, we need to devise a way to detect the version of Python being run and use the proper input() function.

This solution is not completely my own. I found it somewhere on Stack Overflow, and modified it just a bit. 😉 The code below if __name__ == "__main__": is what we are interested in here, but I have provided a full working example. I advise keeping the lines in the global namespace. Wrapping it in a function does not permit for per-case input normalization, a topic best explained in another tutorial.

gist.github.com/le717/6189349

It simply detects what version of Python is being used, and uses that version’s form of input. You may also notice I’ve used from __future__ import print_function to send back the input. Practice what I preach. 😛

There technically is no Py2 and Py3 compatible input. The two, while seemingly the same on the outside, are different on the inside and completely incompatible with each other. Because of this, we have to use Python version detection to allow us to use the proper input implementation. This method allows for input normalization, but again, that is another tutorial. 😉

You now know how to bridge the two most major changes between Python 2 and 3. You may not use this at first, but it could come in handy later on. I think this quote from Swaroop C H‘s great book, A Byte of Python, sums up this lesson perfectly. 🙂

Remember that once you have properly understood and learn to use either of them [Python 2 or 3], you can easily learn the changes between the two versions and adapt easily. The hard part is learning programming and understanding the core Python language itself.

Advertisements

Triangular Reactions

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s