When I started at Treehouse, I only had one mission: Teach Python. Seems easy enough. But I was immediately hit with a bit of a problem. Which version of Python should I teach? Python 2, started in 2000 and slated to lose all support in 2020, is still popular but it’s definitely going to end. Guido already declared there wouldn’t be an official 2.8.

And Python 3, despite it’s slow adoption and early problems with Unicode, is now a strong version of the language. But I knew, I just knew, that if I picked Python 3, I’d get asked why.

They could have hired me for my psychic abilities.

Students haven’t asked quite as often as I expected, but it does come up. I figured I should explain why I picked Python 3 and what some of the major differences are between the two versions of the language.

Why Python 3

The answer I give most people is because Python 2 has been end-of-life’d. The people that work directly on Python have decided that there won’t ever be a Python 2.8. They also decided that Python 2.7, from now on, will only get security updates from the Python 3 development branch. No new features unless someone wants to spend the extra required time to backport them. Thankfully, several people are willing to do this. This has given us the amazing __future__ module full of Python 3 goodies, but that’s not the same as using them natively.

Another, somewhat embarrassing reason, is that I hadn’t had a lot of pure Python 3 experience. I wanted to be able to learn more of the newest version of my favorite language. Python 3 scared me when I first looked at it a year or so ago. It seemed like a big change for no real gain and I had visions of having to rewrite everything I had done to support this new interpreter. I was so wrong.

The impending death of Python 2. My desire to dive further into Python 3. The fact that using Python 3 would give us access to amazing new bits like asyncio. These reasons, and others, convinced me to just use it and nothing else here at Treehouse.

I made the right choice.

Even with all the changes that I’m going to talk about below, learning Python 3 won’t stop you from doing Python 2. Most of the code you’ll write will work on either system with some small caveats. You’ll need to remember to substitute raw_input() for input(). You’ll want to always extend your classes from object. And you’ll want to use the __future__ imports to get the new goodies from Python 3.

Favorite Differences Between The Two

Print is a Function Like It Should Have Been All Along

This right here is one of my favorite new things. When I was teaching Python as a corporate trainer, I’d show people the print keyword. I would then explain how print is secretly a function but doesn’t use parentheses like every other function in Python. Cue confusion when we get to any other function in the language.

In Python 3, print() is a function and has parentheses just like it’s supposed to. This, alone, makes getting into the language so much easier.

Unicode and Strings

Python 2 and 3 both have two types of strings. There are byte sequences which have to be literal characters from the ASCII alphabet. There are also Unicode strings, which can hold onto pretty much any character you want to put in there. In Unicode, you can include other languages and, with the right encoding, emoji. But in Python 2, you had to mark every single Unicode string with a u at the beginning, like u'Hello'. Guess how often you use Unicode strings? All the time! Guess how often you forget to put that little u on a string? Forget the u and you have a byte sequence instead.

So, with Python 3, they fixed it. All strings are now Unicode by default and you have to mark byte sequences with b. Using Unicode is a much more common scenario so it has reduced development time for everyone that does Python 3.

If you have or want to support both, you can still mark strings with u in Python 3, though.

Division With Integers

You would think that math is one of the things that programming languages just get right. And most of the time, you’d be right. But division was a weird one in Python 2.

One of Python’s core values is to never do anything implicitly. You shouldn’t turn a number into a string unless the programmer tells you to, for example. But Python 2 took this a bit too far. Consider this problem:

5 / 2

For most of us, our immediate answer is 2.5, which is, of course, the right answer. But Python 2 said "oh, you only gave me integers so you must want an integer back" and happily returned 2. Well, yes, I did give you integers, but I’d rather have a correct answer than an answer that matches my data types.

Again, Python 3 fixed this. Python 3 will give 2.5 as the answer to that question. In fact, it gives a float (a number with a decimal in it) to every division operation.

input() is Now Safe to Use

And, finally, Python 3 brought an important change to the input() function.

In Python 2, there was a raw_input() function and an input() function. raw_input() was the one you always wanted to use. input() was a great way to have your code do things you didn’t want it to. The reason for this is that input() evaluated whatever came in. So good users would send in 123 and Python, trying to be helpful, would make that into an integer instead of a string. Bad users would send in little, or not so little, bits of Python which would then be evaluated, or run. Cue your software doing things you didn’t ask it to do.

In Python 3, raw_input() is gone and input() no longer evaluates the data it receives. You always get back a string, as we’ve seen in Python Basics.

I didn’t even bring up tab completion in the shell. Or the new next() function for generators and iterators. Or yield from. Or how xrange() became range(). Or for-loop variable leaking, and… yeah, you get the idea. Here’s a great overview to show you even more of the reasons it’s worth it to upgrade to Python 3. It has proven to be an amazing version of the language and I can’t wait to share more of it with you. Also, about adoption, we’re getting closer every day.

9 Responses to “Python 2 vs Python 3”

Python 2 rocks and it is a shame that many are trying to ram 3 down my throat. My reality is if Python 2 has batteries included and is seemingly faster and cleaner than the 3 series, there is no reason to switch. At work I have been putting more effort into making c extensions then moving to the next language series, which is unlikely to ever occur.

2016 and still no reason to switch.
Maybe in my company we are ‘colorblind’ after all these years with Python2 but we do miss next to zero of the things they changed in 3 – but hate too much of it.

Examples:

– why low level twisted style asyncio, having to completely rewrite any synchronous codebase into a nearly non debuggable mess – when there is heavenly gevent?
– why having to type those stupid brackets for print 1000 times a day. print is a development time only tool, which you’ll find in absolutely no final program sellable for money. We absolutely don’t care about academic reasons why there should be brackets for a debugging only tool. Check the p function in ruby, they do understand that there is difference between development/debugging time and run time.
– worst one is the nearly unbearable decision to default strings to unicode objects. As if not 99% of all times anything you need to work with, i.e. inspect, modify, compare is Ascii. Any protocol, any international standard by definition of being international only defines keys in Ascii. Also the values which are of interest to a computer program are Ascii. Interesting in the sense of: Causing the program to actually DO sth valuable. Only the tiny little bit of information entered by and displayed to human users will contain unicode characters – but those bits are transiently passed through the program from and to their destination sockets, unchanged. And for inspection of these we do have, these days, an agreed encoding, UTF-8. Trying to say: Python2 with defaultencoding at UTF-8 is perfect for anybody doing I/O professionally.

(…) I could go on long with that list of problems with Py3, summary is:

We have it all in Python2, its a mature battle proven language for professional people who need to get work done.

As to the 5/2 scenario…. I understand the rationale but if one looks at the CS field of languages, especially statically allocated ones, one embeds and implied casting from one data type to another which most other languages avoid.

Glad to know that we are learning for the long term. Just wish we could start web development with Python/Django sooner. It’s good to know the basics, but it is also important to see the results of your studies in a real-world, working application.