A programmer may try to get you to install Python 3 and learn that. Say, "When all of the Python code on your computer is Python 3, then I'll try to learn it." That should keep them busy for about 10 years.
- Zed Shaw, Learn Python The Hard Way
Yesterday, I started a tiny project that allows you to see the utilization of EWS labs at the University of Illinois. One of my goals for this project was to learn to write Python better. I treat Python as my scripting language; I know what it capable of many, many things, but I don't always know the fastest or best (or most Pythonic) way to accomplish those things. For instance, list comprehensions are something that I consistently need to look up. One thing that I haven't dabbled with at all, however, is writing code in Python 3. The reason I avoided it is because way back when I decided to Learn Python the Hard Way, I read that quote by Zed Shaw, installed Python 2, and never looked back (or forward, as it were).
What's Source Compatible Python?
Source compatible Python refers to code that runs the same way using either the Python 2 or Python 3 interpreter. Doing this is a way that many projects have found is the easiest way to start supporting Python 3. I used this my EWS utilization script as an opportunity to start writing this kind of code, and I learned some tips and tricks for the best ways to do this.
from __future__ import print_function from __future__ import division
Two easy and important changes to make is to import behavior from Python 3 into Python 2, and then write the code as if it was Python 3.
from __future__ import print_function changes the
print() that works almost exactly like the statement. This is the biggest pitfall for Python 2 programmers coming to Python 3.
Arguably the biggest pitfall for new programmers to Python 2 is this:
>>> 1/2 0
Python 3 changes (corrects?) this behavior by casting these
ints to floats automatically, so precision is always increased. This behavior for the
/ operator can be imported into Python 2 with
from __future__ import division.
It's worth noting that
__future__ imports must be the first statements in a script (i.e. they can't come after other imports). See below for one more
__future__ import regarding Unicode string literals.
#! /usr/bin/env python try: # For Python 3.0 and later from urllib.request import urlopen except ImportError: # Fall back to Python 2's urllib2 from urllib2 import urlopen html = urlopen("http://www.google.com/") print(html.read())
Many libraries had their structures change in Python 3. For my project, I had to deal with
urllib. One way to deal with differences is as above: import the same function or object from modules. Try for Python 3 support, then fall back to Python 2 support.
In Python 3, all strings are Unicode. You must take care with how you handle strings; Python 2 allowed text strings and byte strings to be used almost interchangeably, and Python 3 does not. Usually, this sort of thing can be taken care of by deciding to only use Unicode literals by using
from __future__ import unicode_literals, and using
decode to get byte strings from other encodings when necessary.
It's Not Easy
There are many more stumbling blocks when writing source compatible Python. These are just some of a few that I've encountered. Please let me know if you think there's some that I should include here.