Modern Python offers powerful features such as asynchronous programming (using async
and await
) and memory-efficient data processing with generators and iterators. Leveraging these advancements, primarily found in Python 3, can significantly improve your code’s performance and maintainability. This often necessitates migrating existing Python 2 projects. The migration process can vary from a straightforward conversion to a substantial refactoring. To help you navigate this, we’ll discuss some of the crucial differences between the two Python versions.
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; this means k[0:2] would fail. A quick, suboptimal workaround for the code above could just be:
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, that is in for loops, while range() returns lists:
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 is now gone, but it could probably be replaced with a list comprehension.
4. EXCEPTIONS:
Python 2 code with 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:
These changes may break programs in very non intuitive ways:
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 considers the types and then does an integer or a floating point division depending on what it has found. Python 3 is more predictable from this point of view – it always does a floating point division.
Rounding is even harder to make sense of, because some Python 2 versions round numbers down, while others round them up. Again, Python 3 has brought more clarity by rounding up or down to the nearest even number.
There are far more differences – if your code uses (let’s say) urllib, then all call points need to be adjusted for a new syntax. To end on a higher note, I have to mention this automated tool that may be able to deal with this tedious migration task: 2to3.