Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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.
  • 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 it enforces the wrong consistency. Objectively it's neither good nor bad.
  • 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 and enumerate do not have the same methods as list. So, 99% of the time you either convert them to lists with list(), or you 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.

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.

@shayneoneill
Copy link

shayneoneill commented Aug 2, 2021

"Especially in the ML field I wish there would be less Python and more mature languages, Rust, Go, C#, JavaScript"

My dude, Python is a decade older than any of those. In fact for the most part the libraries people are doing a lot of the big data stuff are older than any of those languages (with the possible exception of JS, but JS today isnt the JS of the 1990s) Thats what I dislike about the sudden popularity of python, people not realising its actually a fairly old language thats had a somewhat slow and careful evolution (Though picked up a bit of pace now that the loooong road to Python 3 adoption is finally complete)

@notjames
Copy link

notjames commented Aug 2, 2021

I feel you're being very generous to Python. Guido was a hack developer who learnt nothing from what had gone before. His big idea was "ooh, whitespace makes it look like the pseudocode I see in books. Let's do that.", ignoring the fact that books are carefully typeset, not hammered in at 4am under pressure with whatever random editor is installed on the remote server when you HAVE to patch a newly discovered bug that has brought the service down.

The OOP syntax is just a half-arsed joke that can't decide what its own system is for calling methods on objects, assuming that what you have IS and object, of course. Python is full of entities that are not in fact objects. For example, numbers, and flow-control. Not to mention all those defs just floating about at random.

It is a terrible, terrible language with a core echo-chamber culture that absolutely refuses to accept criticism and in fact takes pride in being criticised because it makes the lousy developers feel vindicated in a perverse Dunning-Kruger Effect way.

I wish we could thumbs up comments. This one is one with which I completely agree.

@grahamnicholls
Copy link

grahamnicholls commented Aug 11, 2021

@muratyaman
Copy link

muratyaman commented Sep 10, 2021

:D ironic to see quite a few comments like:

"you don't know python, maaan"

people are kidding themselves and only deceiving the young programmers about Python!

if a programming language makes me think unnecessarily and reduces my efficiency

(never mind the runtime efficiency! another big topic),

it is not a good one!

no one can defend this:

data = [None] * 100

here is a hard one for Python as it chokes! it is easy in other languages.

class Person:
  def __init__(self, name = '', age = 0, is_fan = False):
    self.name   = name
    self.age    = age
    self.is_fan = is_fan
  # end def

  # without this, method hydrate() does not work;
  # it causes "TypeError: 'Person' object does not support item assignment"
  def __setitem__(self, k, v):
    if k in self.__dict__.keys():
      self[k] = v # FIXME: this causes RecursionError 
    # end if
  # end def

  def __str__(self):
    return str(self.__dict__)
  # end def

  def info(self):
    not_str = '' if self.is_fan else 'not '
    return f'{self.name} is {self.age} years old, and is {not_str}a fan'
  # end def

  def hydrate(self, dictObj):
    for key, value in dictObj.items():
      self[key] = value # this requires magic method __setitem__()
    # end for
  # end def

# end class

p = Person('John Smith', 20, True)
print(p.info())
print(p)

data = {
  'name': 'Jane Smith',
  'age': 21,
  'is_fan': False,
}

print('copying data...')
p.hydrate(data)
print(p.info())

to avoid twitching, I had to use comments to highlight the ends of if/class/for/method blocks!!! ugh!

I know the sophisticated ones will tell me off and show me better ways of doing things

(in reality offering a work around for an absurd unintended side-effect of some features) and say:

learn some python, maaan!

happy coding, everyone!

...using the programming language that you feel comfortable and efficient; the one that makes you love your job, not hate!

@ekeyser
Copy link

ekeyser commented Oct 14, 2021

I believe the only reason Python became a thing was because it was an alternative to Perl. I personally do not think Python is all that great a language. The comments on here from Python advocates indicate that they cannot take criticism.

@ekeyser
Copy link

ekeyser commented Oct 15, 2021

Yeah, what could possibly be disjointed with multiplying a set with an integer ;-) Is that idiomatic? Most definitely since idiomatic means you only know something from extended use of the language itself. What exactly does it say it will do? [None], 0, I mean, if you're trying to figure it out by deduction what would you get from None * 100? Maybe it's a 100 element null set? I'm new to this thread and admittedly I don't code in Python a ton but I'm guessing from the context of the post that this is Python's way of initializing a 100 element null set (or some n-length set in general). There is no way this is "natural" and would agree with @muratyaman. The only way you would know this is exactly what you said - idiomatically. But idiomatic means you know it only from using the language not from inference/intuition/deduction. Why wouldn't you just do [] * 100? Maybe that's a thing in Python, I don't know. Seems more intuitive to me than [None] * 100.

No disrespect but you cannot make something ugly attractive. Alternatively, if something has natural beauty I would argue it would take extraordinary effort to make it ugly. Now, I would understand if something could be powerful and ugly at the same time and you work with what you got. Is Python powerful? My take is no.

Is Python ugly by design? Absolutely and you need only go as far as the constant self argument-stuffing to see this - one of the more bizarre characteristics of Python.

@grahamnicholls
Copy link

grahamnicholls commented Oct 15, 2021

@bratwiz
Copy link

bratwiz commented Oct 15, 2021

@juanfal
Copy link

juanfal commented Oct 15, 2021

@grahamnicholls
Copy link

grahamnicholls commented Oct 15, 2021

@xennex22
Copy link

xennex22 commented Dec 12, 2021

Let's update this with a couple more observations:

  • No constants. No, a convention is not the same as a language feature.
  • Speed. Something between 100 and 400 times slower than C on the same hardware. The dogma tells people that the increase in productivity outweighs the decrease in execution speed. But if your embedded device runs at 0.1 FPS what good is that?
  • Resources. Uses 5 to 10 times more RAM than C. It's dynamic, so you find out at run time, not compile time.
  • Scalability. Large programs just turn into a giant mess.
  • Passing arguments by value vs reference is not intuitive with values of references being used.

@juanfal
Copy link

juanfal commented Dec 12, 2021

I don't care such much about speed issues. Of course, the faster the better, but that's not the goal for an interpreted scripting solve-problems language. You are not building an Operating System with Python or Ruby, but what is really poor and anarchic is the language itself, its grammar and inconsistencies. Long time there for it not to be refreshed with: constants, switch, better loops, more consistency in methods/functions, easier building of classes, stupid indentation (try it with more than 3 levels dropping to 0), etc, etc, etc

@greypanda
Copy link

greypanda commented Dec 15, 2021

This thread should be a book! It's hard to believe my first post was 2 years ago. I made some comments that were my opinion at the time, but more experience means more opinions.

I recently took on a project on a Raspberry PI. Python is considered one of the "ideal" languages for that, since C/C++ compilations can take hours to complete. Although I finished the project, I am not proud or pleased with it. xennex22 hit the Python nail on the head. I'm considering rewriting the app in C++ just to get it running reliably.

So have I completely abandoned Python? No. I think it is still a great tool for getting a basic concept running. You just put the code in a file and run it. But for a "real" application, it is just too clunky to bear.

There are way too many "blessed" libraries that are written by beginners and fail the stress tests. I find myself rewriting much of the code in libraries and just using the pieces I need. ( This is not much better than the libraries in Arduino, which have to be carefully weighed before they are trusted. But maybe they can be forgiven since they are free and written by and for hobbyists. )

I was originally impressed by pipenv since it did away with a lot of the confusion of venv, pip and friends. But then I have to ask "why do I need to have 5 different versions of Python running along with the crazy dependencies that presents?" That is one of the reasons I learned to hate Java -- it seemed like every program required a special minor version to even compile. Every time I forget to prefix a command with pipenv run, I cuss.

So since I am no longer paid to make stuff in the image of the program manager, I am really trying to find a language that is not ugly, performs well, and can run on just about any platform. Good luck to me.

@ekeyser
Copy link

ekeyser commented Dec 15, 2021

As was so concretely and colorfully illustrated by Shayne Oneill, the Python community has its fair share of zealots who find no value in the opinions of others. About the only other community that is/was similar is Perl but at least w Perl they don't pretend that their language isn't archaic or possibly even obtuse. I find it odd that even with so many people pointing out shortcomings with Python that die-hard Python developers will dismiss anyone with any amount of criticism with such extreme rhetoric. I guess everyone else is simply no on their level.

I guess the next topic is what programming language has what kinds of users and enumerating all behaviors and characteristics of each community. ;-)

@xennex22
Copy link

xennex22 commented Dec 21, 2021

And here's some more reasons not to use Python

  • Energy inefficiency. A recent study shows that Python uses 75 times as much energy to accomplish the same goal as would a C program. Think of all the data centers with banks of servers running Python, and the amount of wasted energy that results in.
  • The stupid backward conditional expressions. I'm not sure who thought the assignment should be before the condition, but it makes reading code difficult (but still the dogma that python is simple and clean and easy to understand persists).
  • The reliance on third party tools to fix the broken language. Since dynamic languages can't find type problems until runtime (if at all) then you are told to run a code audit tool like pyrama. Of course, the linters are written in python so select the one you want to use carefully because they are slow. Same with the stupid reliance on white-space for scope - if you criticize it you are told that you should be using tool x (or even that it is somehow purer and therefore better than using braces).
  • The response from the python cultists, as demonstrated in this thread, that any criticism of python means that you are deficient as a programmer or you are doing something wrong or you just don't understand python or you are not using the right additional hack tool to fix the broken language.

@xennex22
Copy link

xennex22 commented Feb 5, 2022

Guido is an arrogant hack. He created a second rate scripting language which languished for a decade before by pure luck it was adopted by Google.

As an example, here is Guido's take on Python vs C++ (direct quotes):
"Python code is ... often 5-10 times shorter than equivalent C++ code"
and
"one Python programmer can finish in two months what two C++ programmers can't complete in a year"
and
Q: "Is C++ better than Python?" A: "If you have to ask, learn Python."

How arrogant do you have to be to claim with a straight face that a Python program is 5-10 times smaller than a C++ program? Or that programming productivity is 12 times high in Python than C++?

"An Empirical Comparison of Seven Programming Languages" finds that writing a program in a dynamic scripting language (Perl, Python, Rexx, Tcl) takes half as long as C/C++ and about half the length. The paper does not explain why the C and C++ programs were the same length and took the same time to write. The number of defects (ie quality) of each language was about the same. I would note that the example program was realitively small and involved string processing, something that favors dynamically typed scripting languages.

"A comparison of common programming languages used in bioinformatics" shows that Python was 90% the length of C++ and about 50% the length of C.

"On the Impact of Programming Languages on Code Quality" shows quality is about the same too.

So boom goes the dogma that Python programs are higher quality (one look at the source for most of the libraries would tell you that). And also we can reject the claims that Python programs are an order of magnitude smaller and an order of magnitude quicker to write.

@Preposterone
Copy link

Preposterone commented Feb 9, 2022

Nice read, I have recently tried to delve into Python when learning algoritms and I was STUNNED by the fact that python doesn't have a simple one-line way to write an indexed for loop. Instead, every for is a for each with top-level range() or enumerate().
Baffling.

@grandslammer
Copy link

grandslammer commented Feb 10, 2022

I recently thought I'd give Python a try and was getting frustrated with several things about it, so I Googled and found this post. Here's what I really don't like about it, and these are really starting to put me off it entirely:

  • Multiple Python versions installed on my PC (forget about v2 vs v3, I'm talking about multiple versions of v3!)
  • Package management hell
  • Virtual environment hell
  • Whether to install vanilla Python (direct from the python.org website), or Anaconda - possibly both!
  • I'm beginning to get slight feelings of "this thing is trying to take over my PC!" (see points above)

Feels terrible from an organisational point of view.

With any other language I've used, if there's an update to the language, you just download it and it replaces the old version on your system. No messing around with multiple versions of the same language.
The same goes for updating packages - e.g. you just run "npm update" inside a project's folder for JavaScript, and boom! It's done.

Forgive me if there are easy fixes to the above, I'm still new to Python. I've looked and cannot find any resolutions anywhere though.

@ekeyser
Copy link

ekeyser commented Feb 10, 2022

That reminds me of the completely hilarious abandonment of pip search support....

xmlrpc.client.Fault: <Fault -32500: "RuntimeError: PyPI's XMLRPC API is currently disabled due to unmanageable load and will be deprecated in the near future. See https://status.python.org/ for more information.">

Yeah, like pip is the only thing on this planet that receives a lot of traffic. Embarrassing. "hundreds of thousands of search calls per hour". Awww, you poor little victim ;-)

ref
https://stackoverflow.com/questions/66375972/getting-error-with-pip-search-and-pip-install

@xennex22
Copy link

xennex22 commented Feb 14, 2022

  • The inability to retain backward compatibility between versions. Sure, languages like C++ evolve with standards, but I can take C source from 30 years ago written under C90 and it still compiles and works just fine under C++17. Backwards compatibility is a thing.
  • Assignment expressions. aka the walrus. To fix an original design mistake there now have to be two operators to do the same thing - assignment and expression assignment. No reason not have done it right in the first place.
  • Python only works in a narrow niche. Mobile, embedded, even desktop are not practical targets for Python. Why now? Because of the speed and memory requirements this language has.
  • Scoping was inefficient and when it got fixed it is now half broken. So you end up with things like a function being able to see variables from outside scope but not make changes to them. And Python is touted as the beginner language which is easy to understand. Not when there are gotchas like this.
  • Default arguments have a life and are mutable so become something other than the default value on subsequent calls. As above, why this non intuitive behavior?
  • Python makes a big deal about leaving out ++ and -- operators because they are 'not easy for beginners to understand' but includes +=
  • True and False are hacks for integer values
  • Lambdas are very restricted in that they have to be an expression and are limited to only one line. So you have to create a function and call that in your lambda expression, which more or less defeats the point of a lambda.
  • The development of a fix it culture around Python. eg Frustrated by incompatibility between Python versions for deployment? Use containers. Can't determine the logic flow if a program because of the invisible elements? Use an editor which shows tabs for you.
  • The hacks needed to cope with the 10000 faces of python versions. eg from __future__ import xxxxx. The only one I want to work does not work from __future__ import braces. And of course, it is not an import at all but uses the import keyword ie it is a hack. Also note the use of not one but two sets of double underscores.
  • The hacks needed to work with a dynamically typed language. eg how is / and // initiative to beginners? Also note that the introduction of the floating point division // broke old code. A cast is clearer because at least a beginner would have some idea what a float might be.
  • The 50 odd built in functions that break any object orientated structure to python. eg len(object) rather than object.len(). But then objects in Python are a cruel hack - looking at you self.
  • There is no forced structure to a python program. Thus people program all sorts of crazy things like mixing inline code along with code in functions. No wonder the quality of most libraries is low. Not everyone should write code that others depend on.
  • The prolific use of assert as a non debugging aid in release software. That would bring me on to the next problem with using Python in a commercial environment - the lack of a pre-processor.
  • Why is python written in C/C++ if C is so bad? You can implement a new language from any other by first writing an interpreter and using that to write a compiler. The interpreter is there, so why no compiler to compile the python written interpreter?
  • The more you look the clearer it is that python is an ugly hack of a language. The emperor has no clothes.

@isaax2
Copy link

isaax2 commented Feb 23, 2022

I'm happy that I'm not alone, I develop apps in since about 15 years in lots of languages and layers (C, C++, C#, Java, Objective-C, Swift, Javascript, LUA, Ruby ... etc). Now I took Python with an existing real project, and it's the first time that I can barely understand what's happening using the "simple and easy syntax".

@Odalrick
Copy link

Odalrick commented Feb 24, 2022

map and enumerate do not have the same methods as list

Can someone explain to me exactly why completely different things should have the same methods?

And another thing:

single-item tuple (tuple,)

I know about the syntax for a single item tuple, and can even agree that it is an easy mistake to make; but for the lite of me I cant think of a single time when I'd actually need a single item tuple.

It's almost as if the thinks the only difference between tuples and list is that one is immutable; but no-one can be that silly can they?

Everyone knows tuples are fixed collections of heterogenous things and lists are variable homogenous collections.

@codingben
Copy link

codingben commented Feb 27, 2022

@isaax2 Same here. I'm a developer with more than 10 years of coding - I never saw complicated language like Python, it's like a different world and very hard to keep it "simple" when your application become bigger and bigger (especially when it comes to PyTest, Typing, etc). Just see [1] how it's complicated.

I can confirm that Python is much much more complicated than Rust. 😄

[1] https://www.python.org/dev/peps/pep-0544

@Reenuay
Copy link

Reenuay commented Apr 9, 2022

Just learn functional statically typed language and you will understand that all those mainstream languages are the same sh*t. For example, you can learn Elm. After that I don't want ever write a project with a non-functional language.

@BrianG61UK
Copy link

BrianG61UK commented Apr 22, 2022

Dynamic Typing.
How can a language that doesn't identify type mismatches at compile time be considered anything other than a toy.
Mistakes in syntax can go unnoticed until they just happen to crash your program at some random point in it's life time.
It's almost as hopeless as the Microsoft Basic was on the first computer I owned as a teen back in the 80s.

@StitiFatah
Copy link

StitiFatah commented May 7, 2022

Dynamic Typing. How can a language that doesn't identify type mismatches at compile time be considered anything other than a toy. Mistakes in syntax can go unnoticed until they just happen to crash your program at some random point in it's life time. It's almost as hopeless as the Microsoft Basic was on the first computer I owned as a teen back in the 80s.

http://mypy-lang.org/

@tworthington
Copy link

tworthington commented May 8, 2022

@BrianG61UK
Copy link

BrianG61UK commented May 9, 2022

I don't think I've had a runtime type mis-match error this century, and I mostly code in dynamically-typed languages. I suppose being able to check at compile time is perhaps a nice to have, where it can actually work, but if it's saving you from bugs routinely then you're doing something else wrong. Probably writing functions/blocks/methods which are too long so you lose track of what you're doing. Python has many flaws, but dynamic typing isn't one of them and adding it won't help.

You never have complicated global data structures and many people writing code that manipulates them?
When the data structures get modified to add new features, you never miss any of the changes needed in any module?

@nslay
Copy link

nslay commented Jun 23, 2022

I love how I can crash my Python scripts in ways you can programs written in native languages. Messages about segfaults and double-free corruption are things you wouldn't expect to see with Python. The worst I've seen to date is silent memory corruption... wow, I just never thought I'd see that in Python! Only knowledge about a native language can provide any clue as to why these kinds of crashes might have happened (and how to workaround or fix them in Python). A newbie computer user isn't going to understand, for example, numpy memory trickery and all the things that could go wrong if numpy doesn't account for shared memory correctly.

Maybe my gripes are more directed toward Python packages. Where do you draw the line between essential packages like numpy and Python, the language? I think numpy played a very big role in Python's popularity. Yet you can really shoot yourself in the foot in worse ways than described in this article. Like C levels of foot-shooting! And it's more mysterious because of how convenient and high-level the language is.

@rednnnno
Copy link

rednnnno commented Jul 1, 2022

The more I think about it, the more the forced spaced scopes remind me of the COBOL/RPG400 days...

I guess it's to be expected; we went from mainframes -> Personal computers -> cloud computing (really just back to mainframes - but on the internet now...)

So I guess it's just a fashion and it works exactly like fashion; concepts are cool for a few years; mostly forgotten about a pulled from the moth-balls back to relevance by some nostalgic geezers and/or some younguns that've never seen it before.

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