Migrating from Python 2 to Python 3

As the world evolves, one may want to take on new opportunities to get better things out of the door, e.g. use the “new” async paradigm or make better use of generators and iterators. This means using Python 3 – and this also usually means migrating large codebases from Python 2. Sometimes this is as easy as flipping the bit, other times it may be better to just refactor the whole code. Let me point out some differences, though.

1. print

This one is easy – most of the time it’s just about translating code from:

print "abcd"

to:

print("abcd")

2. dict keys() and items()

This works in Python 2:

x = {1:2, 3:4, 5:6}
k = x.keys()
z = k[0:2]
# [1, 3]

Unfortunately the return type for keys() and items() is different and non-subscriptable in Python 3 (e.g. k[0:2] would fail). A quick, suboptimal workaround for the code above is:

x = {1:2, 3:4, 5:6}
k = list(x.keys())
z = k[0:2]
# [1, 3]

3. range() and xrange()

The xrange() construct is used in Python 2 as an infinite generator, e.g. in for loops, while range() returns lists, e.g.:

a = [i for i in xrange(23)]
# [0, 1, ... , 22]
b = range(23)
# [0, 1, ... , 22]

In Python 3 range() is a replacement for xrange(), while the range() implementation found in Python 2 in gone: one needs to replace it with a list comprehension.

4. exceptions

Python 2 code on exceptions looks messy:

try:
	raise IOError, "file error"
except IOError, err:
	print err

Python 3 is cleaner:

try:
	raise IOError("file error")
except IOError as err:
	print(err)

5. Rounding and division

Such changes may break programs in very non intuitive ways, e.g:

a = round(122.5)
b = 7/5

# Python 2:
# a = 123, b = 1

# Python 3:
# a = 122, b = 1.4

Long story short, Python 2 looks at the types and does an integer or a float division depending on these types, while Python 3 is clearer from this point of view: it always does a floating point division. Rounding is harder to comprehend: from x.5, Python 2 automatically goes up to x+1, while Python 3 goes to the nearest even number.


There are more differences – if one uses some external library such as urllib then all call points may need to be adjusted. But, to end on a higher note, there is an automated tool that may be able to deal with many of the synthax changes, including the ones mentioned in this text: 2to3.


Leave a Reply

Your email address will not be published. Required fields are marked *