Why Python? Of all of the questions that I have been asked as the instructor of an Enthought Python course, this has been one of the most difficult to answer in a satisfying way.
The answers I have given have always seemed more opinion than fact. Still, if someone asks me what language I recommend for new programmers or for a new project, unless there is a specific reason not to use Python, I recommend Python. And, if I were given a reason not to use Python, I would question that reason, just in case it was not really all that well thought out. So, why Python?
Before Finding Python
Until I encountered Python, I was mostly computer language agnostic. I would learn a language for one of several reasons: hardware availability, organizational preference, package ecosystem, or to try out something new.
My first language was BASIC simply because it was what was available on the Radio Shack TRS-80 computers that someone donated to my school in 1978. My second language was Algol–it is what you typed onto the punch cards to load into the mainframe that I got access to a couple of years later. A preference for BASIC or Algol was simply not a question. I learned the language that was available to talk to the hardware to which I had access.
As an undergraduate studying Computer Science (mid-1980s), language was dictated by the university department. At the time, Pascal was the teaching language of choice, so most CS classes were based on Pascal. In addition you were required to take either FORTRAN (for science) or COBOL (for business); I chose FORTRAN. From there, various campus jobs led me to branch into C and Assembly (working with hardware) and PERL (log processing).
Some years later, jobs and linguistic ecosystems drove language choices for me. I was doing remote sensing; to write routines for the image processing software at the time you had to use FORTRAN. In another environment, I was processing USGS contour maps with C since that was the language of preference there. Even later (late-1990s here), I took a job with a company in the Java ecosystem; so nearly all my code was written in Java. It was in this last environment that I first encountered Python, in the guise of Jython (Python on the Java Virtual Machine).
After Finding Python
In contrast to Java and many of its predecessors, Jython was a pleasure to program in. You focused on solving a problem, not on syntax or the deep intricacies of libraries you had to use. Projects that I could have done in Java were better done in Jython. The code was quicker to write. It was also easier to maintain. The main downside was that Jython lagged Python by several versions and so you could not always count on all of the Python features you expected or hoped to find. Whenever I had the option of choosing a language for a project, I found myself electing to do things in Python.
I can (and sometimes do) relate all this background to people who ask me, “Why Python?” I can even take them through more experiences, details, and several more obscure and probably obsolete computer languages (Occam anyone?). We can compare my favorite language to their favorite languages, examining them feature by feature. However, in the end it is all just opinion, albeit informed by experience.
A Reasonable Answer?
That was where I generally left things until recently, when a colleague of mine pointed me to an article titled “The Origins of Python” (I won’t recap the article, it is worth reading in toto). Still, it actually led me to my first real answer for “Why Python?” Basically, it is because Python was designed from the start around meeting a general user’s (a programmer’s) reasonable expectations for communicating with a computer. In short, it was written for people who want to ask a computer to help them solve practical problems, but who don’t want to spend a lot of time just figuring out how to get started.
As an example, let’s take something simple like printing to the console:
Language | Code |
BASIC | PRINT "Hello World! " |
C | printf("Hello World!"); |
C++ | cout << "Hello World!"; |
Java | System.out.println("Hello World!"); |
Python 3 | print("Hello World!") |
Each language can print strings to the console. Some of these have more quirks than the others for basic syntax, but once you learn the quirks you are mostly good to go. Now try printing something else–integers, floats, lists, arrays,… move on to ever-more complex data types. Which ones work? Which ones don’t? What was your expectation?
In Python your expectation is that it should just work. In all the other languages I have worked with, I would expect the simple data types (strings, numbers) to work; however, anything more complex I expect to require me to convert whatever I am printing into a useful string representation. That can be a lot of work, especially if it is a data structure or object taken from someone else’s library. I have to think about object structure, conversions, formatting, etc. It is particularly annoying when you realize that virtually every other programmer who wants to print that same thing has to take the same kind of detour to solve and debug the exact same small problem.
For my first several years working with Python (mostly in the Jython context), I had no idea how or why a Python print() just worked. It was a delightful surprise that whenever I printed a native Python data structure or object, printing worked without any extra fuss. However, whenever I tried to print some Java object that I had imported into Jython, I soon realized that I had yet another function to write called something like “print_java_object()
“. Ugh. Fairly quickly I found myself avoiding Java objects and data structures whenever possible, choosing instead the closest Python equivalent. Java HashMap? No. Python Dictionary? Yes.
Extensible Expectation
It was only after I immersed myself in a Pythonic culture that I started to learn the how and why of the Python print() function. It turns out that every time you define an object in Python, there is a special __str__() method (typically pronounced as “dunder string method”) that you can override to tell print() how to print it correctly. Not only are you—as the programmer—enabled to write this method by the language, you are expected to write it by the Pythonic culture around you. The idea is that you designed the object and if you expect anyone else to use it (including the future you), you ought to be responsible and take the time to write the dunder string method and be done with it.
Write once. Easily use forever after. No more reinvention of the print wheel in every programming shop around the world that happens to use your object. What a radical idea.
This idea in Python is not a one-off in the language (see Python’s governing data model). There are many dunder methods that I can use to hook my custom objects into Python’s system of standard expectations that things should just work. Should different instances of my object be sortable? If so, provide methods for __eq__(), __ne__(), __gt__(), __lt__(), __ge__(), and __le__(). Suddenly Python knows how to handle comparing different instances of my object with any of the comparison operators: ==, !=, >, <, >=, and <= (see Python’s PEP 207). I would have loved that when trying to sort satellite images by date; my image object (which had a date attribute) could simply have defined these methods to tell Python which images were less than others by date. Sorting would have suddenly been possible without any extra effort. Perhaps it is meaningful for instances of your object to be added? If so, define __add__() and now “object1 + object2
” can provide a valid result. That is much more in line with my expectations than writing a Java-like “object1.add(object2)
“. Wow. If I am modeling particles in physics or oil droplets in chemistry, I can tell my objects how to add themselves.
Pragmatic Usability
The dunder system is just one small aspect of the ways in which Python has elevated usability by prioritizing meeting a general user’s expectations over some theoretical and abstract notion of computer linguistic perfection. Simple things like docstrings, the help() function, and even nesting by indentation all conspire to make Python easier to learn, to read, to maintain, to write. Python’s ethos of strongly encouraging the language designers, library developers, and each programmer to put in the effort to do the right thing for the user from the beginning makes the Python language and ecosystem much better for everyone involved.
So, if your favorite language is not Python, examine how something simple like printing to the console works. Ask yourself does the language in general stretch to fit your reasonable expectations of what should happen? Or, do your expectations need to conform to the language?
If your answer to the last of these questions is “Yes”, then perhaps you should be asking instead: Why not Python?
About the Author
Eric Olsen holds a Ph.D. in history from the University of Pennsylvania, a M.S. in software engineering from Pennsylvania State University, and a B.A. in computer science from Utah State University. Eric spent three decades working in software development in a variety of fields, including atmospheric physics research, remote sensing and GIS, retail, and banking. In each of these fields, Eric focused on building software systems to automate and standardize the many repetitive, time-consuming, and unstable processes that he encountered.
Related Content
4 Reasons to Learn Xarray and Awkward Array—for NumPy and Pandas Users
You know it. We know it. …
Extracting Target Labels from Deep Learning Classification Models
In the blog post Configur…