What I dislike about Python

Sunday, May 22, 2016

try: assert Python == great

Python is my favorite programming language. It’s easy for beginners without limiting experts, it’s fun to use, and there’s a great community of people working on it. However, no language is perfect, and occasionally I get frustrated by its limits.

Quite a few of these things are a consequence of Python’s strengths. I’ll try to at least nod at them, without turning this into the “What are your biggest weaknesses?” of programming posts1.

except Python2and3Exception:

The biggest problem is not that Python 3 is poorly done, that Python core developers are refusing to release 2.8, or that people sticking with 2.7 are too stubborn.

The biggest problem is that making substantial changes to a programming language is intrinsically hard. When you maintain a programming language, your users aren’t just people firing up Vim or PyCharm today and starting a new project—they’re people who maintain projects written years ago, possibly before 3 was even announced. They’re people who don’t write Python anymore and have let their program go fallow for years, even though people still use their code today. And by extension, they’re all the users of that code, often people who have never heard of Python2.

All of those people are impacted by your change, but only some of them benefit from it, often in indirect and invisible ways. Eventually the benefit of better Unicode handling might reach users when pasting München into a travel site doesn’t break everything, but that probably doesn’t console the programmer fixing hundreds of places that deal with text.

Another way to look at this is to compare it to a UI change. For all the (often justified) complaints about sudden changes to Facebook, adopting to a change in a social network is easy for most people. You retrain yourself to use the new interface, and you’re done. But even once you train yourself to code using the modifications to the language, that still leaves thousands of lines of code that need to be converted. Even when the conversion is straightforward, it’s not particularly fun and there’s always the risk of introducing bugs.

Leave the handling of emoji, math symbols, and 99 percent of the world’s alphabets forever fragile is clearly worse, so making a slow transition to Python 3 and warning people of any changes that could break anything far in advance, is the best compromise.

While I’m sure there are ways the transition could have been handled better, I think many of the changes are necessary and that the community will get through this. In the meantime, though, there’s a huge amount of disparaging talk around Python, leading to non-Pythonistas thinking the community is in civil war and that they shouldn’t learn Python.

except TooManyOptionsException:

Python has a huge number of libraries—there are custom libraries to search IMDB, create random but grammatical sentences, and conduct research on gravity waves. The downside of this (awesome) enthusiasm for libraries is that common problems get solved over and over again. Solving the same problem repeatedly does increase the odds of someone coming up with a clever and powerful solution, and of course, if you want to write another implementation of an math library for fun or practice, be my guest. It’s just a proliferation of serious libraries3 that solve the same problem makes it really hard to pick one:

  • Need to handle dates? There’s datetime, delorean, arrow, dateutil, pyx…

  • Need to write a command line? optparse, argparse, click, optik, docopt…

  • Need to write tests? doctest, py.test, nose, fox, unittest2…

My impression is that GUIs and concurrency also have too many choices. I’ve done absolutely nothing with those things in Python, so I can’t really comment.

It might seem like there are also way too many libraries for interfacing with different data formats (JSON, XML, YAML, CSV, etc.), but that complexity is mostly a feature of the outside world, not of Python. Once you’ve figured out you need to use JSON, your options in Python are pretty clear cut—just use the JSON library built into the language, or .

So if an undifferentiated smorgasboard is bad, what is good? Ideally, you want there to be a clear frontrunner or two for each category (or each niche in each category). Web frameworks are a good example: Django’s good if you want a batteries-included framework, Flask is good if you want a minimal framework, and Bottle’s good if you want Flask but with slightly more minimalism and slightly less popularity. There are other contenders, but as they’re significantly less popular, it’s reasonable to set them aside at first, as there aren’t as many fellow users to learn from or supporting libraries you can snap on them. That doesn’t rule them out, necessarily, but it helps you narrow your options if you’re not sure what to pick.

except DynamicLanguagePerformanceException:

As a dynamically typed, interpreted language, Python can only do so much for speed and static checking. Of course, there are efforts to address this, like PyPy, Cython, and mypy, and they represent interesting and useful variations on “vanilla Python,” aka CPython. However, these variations are clearly alternatives, and you don’t get the full speed and static checks of say, Rust, C++, or D. In some cases, what you’re writing might not be Python anymore.

I don’t build huge programs, graphics that need to be optimized to death, or mission-critical software that absolutely cannot fail, so this tradeoff is reasonable for me. It is a little unfortunate that there’s a significant speed penalty when using Python out of the box, and I don’t have the safety nets of stronger type checking, though.


These things bug me about Python, but I still think that it’s a great language.
After all, these things are the price we pay for all of the great features of Python. We pay a small speed penalty for flexibility, having libraries for everything means a few too many choices, and for all the pain of breaking backwards compatibility as Python 3 did, it was necessary.

Further Reading

  • This is inspired by similar lists about Python by Titus and Jacob Kaplan-Moss, and Steve Losh’s post on Mercurial’s shortcomings

  • After I came up with my list but before I published it, the Python subreddit had a similar thread.

  • If you’re motivated by reverse psychology and now want to learn Python, check out Tori Dykes’ excellent post on Python tutorials.

  1. Programmer: What is your biggest weakness?

    Haskell: Sometimes people are nostalgic for the spontaneity of runtime type errors when they code with me.

    Lisp: It’s hard to know where to start when you can do anything.

    C: I’m so fast, I sometimes give noobs whiplash.

    Javascript: I get so much attention these days, it’s distracting.

    Python: I’m such a hotshot at scientific computing, people forget I’m a web whiz. 

  2. If you’re one of them, Spotify, (the AI of) Civilization IV, and many websites, including Reddit, are all written in Python. 

  3. In other words, not including libraries someone wrote in a weekend for fun and released online a big “not ready for production use” warning on top of it.