Skip to content

Instantly share code, notes, and snippets.

@RobertAKARobin
Last active September 23, 2025 17:05
Show Gist options
  • Save RobertAKARobin/a1cba47d62c009a378121398cc5477ea to your computer and use it in GitHub Desktop.
Save RobertAKARobin/a1cba47d62c009a378121398cc5477ea to your computer and use it in GitHub Desktop.
Python Is Not A Great Programming Language

Python is not a great programming language.

It's great for beginners. Then it turns into a mess.

What's good

  • A huge ecosystem of good third-party libraries.
  • Named arguments.
  • Multiple inheritance.

What should be good

  • It's easy to learn and read. However, it's only easy to learn and read at the start. Once you get past "Hello world" Python can get really ugly and counterintuitive.
  • The Pythonic philosophy that "There should be one -- and preferably only one -- obvious way to do it." As someone who loves working within rules and rigid frameworks, I love this philosophy! As someone who writes Python, I really wish Python actually stuck to this philosophy. See below.

What's "meh"

  • Forced indentation. Some love it because it enforces consistency and a degree of readability. Some hate it because they think it enforces the wrong consistency. To each their own.
  • Dynamic typing. There are lots of dynamically-typed languages and lots of statically-typed languages. Which kind of typing is better isn't a Python debate, it's a general programming debate.

What's bad

  • 400 ways (more or less) to interpolate strings. This prints "Hello Robin!" 3 times:

    user = {'name': "Robin"}
    print(f"Hello {user['name']}!")
    print("Hello {name}!".format(**user))
    print("Hello %(name)s!" % user)
    

    If there was a unique and obvious use-case for each of these then that would be one thing, but there's not.

  • 69 top-level functions that you have to just memorize. GvR's explanation sounds nice, but in reality it makes things confusing.

  • map doesn't return a list, even though the whole point of a mapping function is to create one list from another. Instead it returns a map object, which is pretty much useless since it's missing append, reverse, etc. So, you always have to wrap it in list(), or use a list comprehension, which, speaking of...

  • List comprehensions are held up as an excellent recent-ish addition to Python. People say they're readable. That's true for simple examples (e.g. [x**2 for x in range(10)]) but horribly untrue for slightly more complex examples (e.g. [[row[i] for row in matrix] for i in range(4)]). I chalk this up to...

  • Weird ordering in ternary/one-line expressions. Most languages follow a consistent order where first you declare conditions, then you do stuff based the on those conditions:

    if user.isSignedIn then user.greet else error
    
    for user in signedInUsers do user.greet
    

    Python does this in the opposite order:

    user.greet if user.isSignedIn else error
    
    [user.greet for user in signedInUsers]
    

    This is fine for simple examples. It's bad for more complex logic because you have to first find the middle of the expression before you can really understand what you're reading.

  • Syntax for tuples. If you write a single-item tuple (tuple,) but forget the trailing comma, it's no longer a tuple but an expression. This is a really easy mistake to make. Considering the only difference between tuples and lists is mutability, it would make much more sense to use the same syntax [syntax] as lists, which does not require a trailing comma, and add a freeze or immutable method. Speaking of...

  • There's no way to make dicts or complex objects immutable.

  • Regular expressions require a lot of boilerplate:

    re.compile(r"regex", re.I | re.M)
    

    Compared to JavaScript or Ruby:

    /regex/ig
    
  • The goofy string literal syntaxes: f'', u'', b'', r''.

  • The many "magic" __double-underscore__ attributes that you just have to memorize.

  • You can't reliably catch all errors and their messages in one statement. Instead you have to use something like sys.exc_info()[0]. You shouldn't have a catch-all in production of course, but in development it's very useful, so this unintuitive extra step is annoying.

  • Dev environments. Setting up an environment is a problem in any langauge, but other languages have solved the problem better than Python. For example, while npm has its warts, it is widely accepted that a fresh environment should be set up with npm i && npm run [script]. Meanwhile each Python project seems to require a unique mish-mash of pip and pipenv and venv and other shell commands.

What's bad about the culture

Most programmers will acknowledge criticisms of their favorite language. Instead, Pythonists will say, "You just don't understand Python."

Most programmers will say a piece of code is bad if it's inefficient or hard to read. Pythonists will say a piece of code is bad if "it isn't Pythonic enough." This is about as helpful as someone saying your taste in music is bad because "it isn't cultured enough."

Pythonists have a bit of a superiority complex.

@KDean-Dolphin
Copy link

@dtonhofer

Prolog (1980s-grade psychedelics),

Hah! No, Prolog is absolute genius once you understand how it even works (i had to reset my assumptions).

I’m happy to be wrong. I’ll give it another look, with the benefit of a few decades’ experience.

If there were some serious investment in Logic Programming instead of everyone throwing money at trying to reinvent a square wheel with the whole JavaScript ecosystem (a practical joke, shurely?) one might see some progress in computer science. There are a lot of excellent ideas out there.

I’m with you on JavaScript; it suffers from the many of the same issues as Python, but the language appears to be better managed, and there are some things in TypeScript that I really like. The build system is horrible, though.

Meanwhile, I guess there is Mercury (underappreciated too, needs a proper IDE)

I’ll take a look.

@RobertAKARobin
Copy link
Author

Added a bullet for setting up dev environments.

@iharob
Copy link

iharob commented Jun 11, 2024

What have you tried with C++ when creating a UI? What didn't work? How can C++ development be any slower than using a shitty language that forces you to stare at a screen to make sure you indent properly? I'm looking at GTK, C++, Eclipse, Cmake. I'll never in my life touch Python, it sucks ass that bad. I'm mostly looking to create something that takes minimal space and works as fast as possible so even my old phones can run it. I want to be able to point my old phone at the printer and use it's camera and broadcast it via Wifi so I can view it on other computers and phones while being able to also control the printer.

For C++ GUIs, I have written a wxWidgets GUI for graphically designing power system survivability simulations. It's been a while, but wxWidgets is like Microsoft Foundation Classes, but cross platform. It uses lots of preprocessing macros! And more recently I've used Qt to design a plugin for MITK. I made a mesh editor plugin for fast 3D segmentation annotation for blob-like organs in medical images.

C++ GUI development is slower mostly because it involves having to compile every attempt. Every change you make requires compiling to test! And that's very slow for large projects. When you have a compilation error, you have to compile again after fixing the error! You also have to spend the time to setup the build system to pull in all the dependencies (include paths/library paths) to even build the thing in the first place! GUI toolkits like Qt are massive with hundreds of include files and dozens of libraries... you need to use something like CMake that can navigate the numerous includes/libraries of a GUI toolkit like Qt. On top of CMake, knowledge of library dependencies in Qt really helps!

For the end users, you have to do something like ship the Qt libraries and make sure those users have the proper dependencies or redistributables installed. Versions of dependencies is also an important consideration as different versions can break ABI! That's when you get dreaded symbol errors in Linux. Or you'll have to use something like Dependency Walker to figure out which symbols are missing on Windows.

Now in Python... you just import some Qt module and can instantly start making windows, buttons, text boxes, combo boxes, etc.... I had a colleague make a fancy network topology editor with PyQt in just a matter of hours! This time frame would be nearly impossible in C++! The key here is that you don't need build systems or compiling to make changes and test GUI changes or functionality. It just works out of the box with scripting languages like Python!

What do you get out of C++? Your program is probably going to run faster and it's likely more correct owing to all the compile-time type checks! What do you get out of Python, or other scripting languages? You'll be able to try things faster and with no project bootstrapping overhead.

Seriously?

More frequently than I wish. Python can break backward compatibility even if you "freeze" the packages. One outstanding case: PyYAML-5.4.1 for python 2. Yes, Python 2 is deprecated, but some project I know is still using it. It shouldn't be that hard to use the same versions used originally and it should run smoothly.

Another one: The advanced build systems like CMake/Qmake and the more recent ones for Qt/C++ are simply awesome. They allow you to do all sorts of things. The project I am working on right now uses a bunch of vagrant machines to run simple python programs. Not only that, but it needs a lot of scripts python/bash to setup the environment. It is simply extremely hard to setup the development environment. With CMake you can write elegant and simple "bootstrap" scripts that produces ready to run binaries, configuration included.

Want to use docker? Ok, just try on a new mac with Apple Silicon chip in it and this setup.

Next: Slow because you need to recompile. Well, you probably don't know it but, if you set it up properly you only need to compile the unit you're working on. With my current python setup it not only takes several minutes to run the startup script (which is generating configuration files and other crazy things pythonists think are cool), but you have to actually do it because you MUST restart uwsgi every time you change a character in the code.

@bakoontz2
Copy link

bakoontz2 commented Aug 9, 2024

@dtonhofer Python is just a worse Perl.

Amen. For grins, I spent 6 hours today writing a "simple" python script that parses a file, selects some matching lines using regex, categorizes them into two lists, combines them under certain conditions, then greps another list generated from another file for matches.

And then I wrote it in perl. In under 30 minutes.

Sure, I've been using perl since the pink camel book. But even if I subtract out the time spent doing Google searches for silly stuff like "how to create a class instance variable in python" (in a constructor, silly!) and setting many, many print statements to figure out why a two-nested-group regex match is returned as a list of tuples (never mind the fact that the list itself is mutable), and that python "re" doesn't support multiple group matches (but python "regex" does, but good luck Googling that, because you get all the regex hits for "re"), I still spent about 3 hours on it. It shouldn't be this difficult and arcane.

And call me old-school, but I'm pretty certain that data encapsulation is a necessary component of any language that claims to be object-oriented. Which makes python not an object-oriented language, despite what Pythonists want you to believe (I believe this quote sums up the iron-clad reason why python doesn't include encapsulation: "After all, we're all consenting adults here." )

@nilslindemann
Copy link

nilslindemann commented Nov 17, 2024

What's Good

I agree to these points and could add many more.

What should be good

That's a bit blurry, so I can not criticize or agree.

What's "meh"*

Forced Indentation
Okay, that can create problems, like indentation getting lost when copying from the Internet. That happened once to me since I use Python. In practice, it is no problem.

Dynamic typing.
What are you missing in today's Python type system?

To the above I would add:

Verbose syntax for dataclasses

One needs to write "class" four times before using the first data. Python needs a data keyword to create data (structs in C, I guess), which would be close to JS expressiveness.

No let block defining space for temp variables

Python does not have that:

let foo, bar:
    baz = 3
    foo = baz * 2
    bar = baz * 5
# foo is 6, bar is 15, baz is not known.

in JS, I can write:

let foo, bar; {
    let baz = 3;
    foo = baz * 2;
    bar = baz * 5;
}
// foo is 6, bar is 15, baz is not known.

No section blocks

"A description of what follows. You can fold this in your editor":
    # here code

What's bad

400 ways (more or less) to interpolate strings
I also dislike using "%" for string interpolation. I use f-strings, if possible. The .format(...) syntax is needed when the format string is inside a variable. That makes one obvious way to do it for every use case and one way, probably kept for backwards compatibility. Not too bad.

69 top-level functions
Why do you need to memorize them? Your IDE has autocomplete, you can print out a cheat sheet, or keep that site open as a pinned tab. Also, your brain has memorized thousands of words in your mother tongue and other languages. When you use Python daily, you will soon have memorized these little lib function names too. I never have to search for them, working is very productive. list, set, dict, print, try to memorize their equivalents and their usage in Java or other languages.

map doesn't return a list
And that makes sense. If you want to map thirty functions over the list you don't want to create a new list in memory each time. And is wrapping in list(...) really so ugly? It is explicit and short. I not just got used to it, I started to like it. Same with generators, iterators, context managers, ...

[[row[i] for row in matrix] for i in range(4)])
Whatever you are trying to do here, you can and probably should write

for i in range(4):
    for row in matrix:
        mylist.append(row[i]) 

The next point is the same, these shortcuts should not be used when the task is complex. Use a normal if / for block statement.

Syntax for tuples
It is a short syntax, but I find it intuitive. I have never run into that error in practice, as far as I remember. How often did you use a one element tuple? And how often have you run into that specific error and were not able to quickly find its cause? Some things just have a short syntax, and it does not hurt. Would you complain about string literals being wrapped in just " and "? I guess no, because you are used to it. (for the records, you don't even need the brackets, you can write mytuple = 1, and I like this!)

Frozen dict, frozen objects
For a frozen dict, create a subclass and overwrite __setitem__. There are libs for other frozen objects. But for what do you need frozen things? I never did.

Regular expressions have a verbose syntax.
Accepted, JavaScript is better in object access syntax and simple regexes. But try to write a complex regex in JS and you will experience pain, while in Python you have re.VERBOSE. Ok, I once figured out a smart workaround for Javascript.

Goofy string syntax
Same as with the tuple syntax, it is often used, and I like that it is short. What would be a non-goofy syntax in your opinion?

Magic underscore syntax
I think it is very expressive. I also just have __init__ __name__, __main__, __slots__ and __pycache__ in my memory. For everything else a Google search or print(dir(<thing>)) or print(help(<thing>)). 90% of these I have never used. You do not need to memorize them.

No Exception catch-all

I do not understand.

try:
    ...
except:
    ...  # Voila, nearly all errors catched - including those you never intended to.

More info.

Many dev environments

Yeah, I did not like that too. But today everybody seems to use venv or no virtual environment, it has gotten better.

@VikVin
Copy link

VikVin commented Mar 10, 2025

This thread is whole LOL. LMAO

My sis (3rd year in graduation) having a code test for an interview and asked for help...
Her classmates selected python to do the code and so is she.

As there is lot of hype being in, So... I too thought of giving a try and learn.
Also, have been planning to learn never got a reason.

As soon as I begin, I baffled with indentation as syntax and then for scope.
Just imagining consequences of overlooking the indentation while copying code or something
that gonna create a hell of mess and security constrains.

Just by going through the concepts. I didn't understand reason the hype is like it's best for everypurpose.
Thought that am I only the one? luckily this thread save me.

Then with intro of new forms of unnecessary things, methods and dependencies.
I amazed, how it survived with out buzz of it's ridiculousness.

I like to create things of my own, rather than falling much on dependencies.
For me programming is that being independent.

For prototyping, yes. It is quick and easy for small blocks of code to Test.
Till there it's fine, if goes further more will be a pain in the ass.

My view is like, it will only be ok for DataScience and where in need of minimal code like testing algorithms.
Where the people don't need to have much need to understand primitives and their reasons.
Except only to just get work done.

Apart from that don't see much of a use. Except to create more confusion and a push towards wilderness for learning python.

A little LOL : https://www.youtube.com/shorts/lqjeojLHQyk
Have Fun Programming... :-)

@svilst
Copy link

svilst commented Apr 24, 2025

I would like to share something that I consider a principal issue with python. I think of functions as one of the most important abstraction in programming, or even the most important abstraction. It is fucked up in python. Yes, the named arguments is a good feature. But let's talk about how can you reason about a function input and output. The input can be hidden behind the infamous args and kwargs utility. They are passed in an invisible way and you just don't know whether they exist and where they are used. You have to trace all calls and to inspect all internal usage in order to find out. Someone can say that it is a bad practice, but I consider it a wrong utility that encourages wrong usage. Now let's reason about the return result. Since it's a dynamic type we don't know, it can be string, json, none, anything. And even more! The return result type can vary depending on one of those invisible input arguments that are so conveniently passed. So, in essence we can end up with a function that has no strict notion about input and output, it breaks up the most important abstractions in programming. This is my experience from a real world usage, and the code is written by people who are fond of the "pythonic" way of doing things. It's just horrible.
And yes, the forced indentation is bad, it makes the code less readable to me.

@nilslindemann
Copy link

@svilst

How can you reason about a function input and output.

By adding type signatures.

The input can be hidden behind the infamous args and kwargs utility.

Annotate them too.

Now let's reason about the return result.

Use type signatures for that too. To denote different return types, separate them with |.

And yes, the forced indentation is bad, it makes the code less readable to me.

Okay, in that case, it is probably best to stay away. Pythonistas dont like bracket revoluzzers :-D

@xennex22
Copy link

xennex22 commented May 3, 2025

This misses the point - Python as a language is terrible, and using third party tools and other hacks does not change that.

Type signatures are not enforced, you have to run a third party tool. I've never seen them used in the wild and are constantly forced to dive into some library to see what a function is actually returning.

Likewise getting rid of the forced indention is just another third party hack to repair a feature of a bad language.

@nilslindemann
Copy link

Type signatures are not enforced, you have to run a third party tool.

It is not difficult to get that working in VS Code. It will suggest you to install the related Microsoft hosted package, which includes a type checker, and you are ready to go.

Likewise getting rid of the forced indention is just another third party hack to repair a feature of a bad language.

I can not change the way how you look at Python. But in practical application, indentation is a rather negligible detail which does not decide if the code gets written. That would be the availability of documentation and packages, the support of the user base, and the elegance of the language syntax.

@tworthington
Copy link

tworthington commented May 4, 2025 via email

@nilslindemann
Copy link

The handling of control structures ...

I would love to see some examples.

and numbers is as far from elegant as you can get; they're a kludged together mess.

Ditto

And the total lack of enforced structure to definitions and "classes" leads to the worst sort of jigsaw code (...)

Ditto

And, yes, the whitespace is a dumb idea which is a problem in real life. (...)

Ditto

@brettwhitty
Copy link

Get off my lawn.

Very well said. A trash language that people only believe is good because they were born sometime after 1990 and their CS undergraduate degree was sub-par; so they didn't learn any other languages, or even basic theory of computation. And most of the devices they used growing up had a GUI, and many only a single button.

The likelihood of one saying a virtue of Python code is its readability is inversely proportional to the amount of code you've read and written in different programming languages. Most Python code I've seen and had to debug looks like absolute hot garbage.

Think of the pile of garbage Python 2 code just rotting away on Github for the last 10-15 years; and that code was written by people who were early adopters, so they went out of their way to learn the language. So that's the good code.

@nilslindemann
Copy link

I now understand that this gist is just an outlet for malicious people who want to project their hatred onto Python without providing or addressing any factual arguments.

@ZehMatt
Copy link

ZehMatt commented Aug 23, 2025

I now understand that this gist is just an outlet for malicious people who want to project their hatred onto Python without providing or addressing any factual arguments.

You clearly have not read them.

@brettwhitty
Copy link

brettwhitty commented Aug 23, 2025

I now understand that this gist is just an outlet for malicious people who want to project their hatred onto Python without providing or addressing any factual arguments.

I appreciate your passive aggression.

I didn't repeat all the points others have made because they are all correct, at least the ones about Python being a hobby language with serious deficiencies that should have been addressed years ago were it a real production-ready language for adult professionals doing serious work. Any language can wrap a C library with an interface and call it a module. The language itself doesn't deserve any credit for that. That's stolen valor.

Semantically significant whitespace is sociopathic. And it really doesn't make any sense in modern times where we are developing across platforns, in webpages, etc. etc. Relying on the consistency of whitespace is stupid; doing it to force a certain behavior on others to impose your esthetic preference is beyond stupid. That's malicious intent.

[An IDE can take care of the whitespace issue! As it can with any language, so why does it even matter? Why purposefully choose an invisible character as your code block delimiter? That's indefensible in the abstract.]

How many years does a language need to exist before it gets a stable tool ecosystem? And when that fails to ever happen --- well here's a solution --- add another layer of complexity and confusion, just do a full local install of the entire runtime for every single throwaway script somebody wants to run. That's prosocial. That doesn't harm anything to do that.

And as another commenter said, you really didn't read (or maybe have comprehension issues) if you don't think the jump from Python 2 to 3 didn't cause a lot of problems with maintaining garbage legacy code.

@tomvanschaijk
Copy link

tomvanschaijk commented Aug 23, 2025

Feel free to delete my contribution, but I'd just like to thank you for over a year of being able to laugh my ass off whenever new comments appear :-D I'm not one to actively contribute to language wars, I have my own preferences, and whatever somebody else uses or what people think about my choices is the least of my concern, To be fair, I'm firmly in the "Python, no thx lol" camp after working on a few bigger projects that relied mainly on Python, but as long as I can limit my contact with it to a few small prototypes and toy examples here and there, I'm fine. I don't want to dive into the back and forth, cause it's like religious arguments: it's just a yes/no battle anyways. But I've had my fair share of chuckles reading all contributions so far, for which I'm grateful. I'm counting on more! And to the people losing their minds over this: it's a programming language :-D we're going to be dead at the end of this, don't lose sleep over what somebody else thinks about the little letters you type :-D (but by all means, keep going at each others throats)

@Odalrick
Copy link

Semantically significant whitespace is sociopathic.

I can understand most problems people have with Python, but the absolute vitriolic hatred of white-space is just baffling.

I can understand not liking it; but beyond the dislike of braces on the end or start of a line...?

invisible character

If you can't see white-space, I advise you to get your sight checked; you might be blind.

[An IDE can take care of the braces issue! As it can with any language, so why does it even matter? Why purposefully choose different representations of code block delimiters between human and computer? That's indefensible in the abstract.]

You better not be using indentation in your C-code, or whatever you're using! Or else I'm going to laugh and point at you.

@lampuiho
Copy link

lampuiho commented Aug 26, 2025

If you can't see white-space, I advise you to get your sight checked; you might be blind.

try copying some code snippet or try to have scoped execution.
Python people also seem to have unhealthy obession of new lines. Every line of statement is seperated by an empty line. On my 720p screen, I lose track pretty fast what scope they are supposed to be in.

You better not be using indentation in your C-code

People also do single line stuff with simple statements.

@Odalrick
Copy link

try copying some code snippet

I do it all the time. Selecting the text to copy is harder than fixing the white-space.

try to have scoped execution.

What does that have to do with white-space?

On my 720p screen, I lose track pretty fast what scope they are supposed to be in.

I don't think I ever had one of those. 340 in the nineties of course, but even then that was more a limitation of the computer than the monitor.

Still, look up: everything is in the scope of the first def you see,

People also do single line stuff with simple statements.

Yeah... your point? Are you trying to say multiple statements are "simple" so often that it bothers you? To me preventing idiots from trying to be too clever is a feature.

I'm not saying Python is perfect; and I can see why people would dislike is intensely.

Except for the white-space issue, if anything the common usage of "{}" in other languages should be worse, as they are difficult to type on some keyboard layouts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment