On many forums, discussions between devs and several blogs, I saw a lots of articles in which Python is mentioned as a bad or ugly language; but why is it so?
I find Python awesome: building everything fast, easy to read and to learn the basis, etc.
But whenever I ask to my fellow developers, nobody gives me a constructive answer; so what is your opinion about it?
Happy coding !
Latest comments (70)
While Python is widely celebrated for its simplicity and versatility, it also presents several challenges that can complicate its use and maintenance, especially for those transitioning from other programming languages. Here are some notable issues, along with comparisons to languages like Java, C#, and JavaScript that often handle these aspects more gracefully:
Multiple Python Versions: Managing multiple installed versions of Python can lead to confusion and wasted drive space. Unlike Java or C#, where the version management is typically more straightforward, Python's complexity often results in issues when installing packages, as it’s unclear which version they are being installed into.
Pip Versioning: Each Python version can have its own pip, creating fragmentation in package management. In contrast, languages like JavaScript use npm globally, minimizing these conflicts and streamlining dependency management.
PATH Limitations: While multiple versions of Python can be installed, only one can be referenced in the system’s PATH at a time. Other languages, such as Ruby, manage environment configurations more effectively, allowing developers to switch versions without breaching character limits.
Dependency Management: Python's dependency management can lead to file duplication and conflicts, with leftover sub-dependencies complicating the ecosystem. In languages like Go, dependency management is handled more transparently, avoiding such issues and ensuring a cleaner workspace.
Virtual Environment Management: The existence of multiple tools for virtual environment management (e.g., venv, pyenv, conda) adds unnecessary complexity. In comparison, languages like C# use a unified approach with .NET, reducing the need for multiple environment managers and simplifying project setups.
Inconsistent Best Practices: The lack of a unified approach among Python developers regarding best practices can lead to varied implementations. Other languages, such as Java, have established conventions and frameworks that promote consistency and ease collaboration.
Lack of Pre-Installation Warnings: The Python installation process does not adequately inform users about potential pitfalls. In contrast, many other languages provide clearer guidance during setup, helping developers avoid common mistakes from the start.
Default Installation Issues: The default Python installation is often not suitable for project work, leading to conflicts later. Languages like C# encourage the use of dedicated project environments from the beginning, which reduces the need for corrective measures down the line.
Compatibility Information: When installing packages, Python does not always provide information on compatible versions, which can lead to time-consuming troubleshooting. Other ecosystems, like Node.js, typically make version compatibility explicit, helping developers avoid unnecessary headaches.
Inconsistent Library Behavior: Variability in how libraries behave across different Python versions can lead to unexpected issues. Languages like Java have stricter versioning and backward compatibility rules, which contribute to a more predictable development experience.
Performance Concerns: Python can be slower than other languages for CPU-intensive tasks. In contrast, languages like C++ or Rust offer better performance for compute-heavy applications, making them more suitable for certain use cases.
Whitespace Sensitivity: Python’s requirement for precise whitespace and indentation can make scripts difficult to read and maintain. Other languages, such as C# or Java, allow for more flexible formatting, which can improve readability without risking syntax errors.
PATH Configuration Challenges: Setting up the PATH variable correctly can be frustrating in Python. In contrast, languages like Ruby provide clearer tools for environment management, easing setup for new developers.
Global Interpreter Lock (GIL): The GIL restricts true concurrent execution in multi-threaded Python programs. Other languages, like Java or C++, allow for true multi-threading without this limitation, enabling better performance in concurrent applications.
The answer is simple, python is not.
Wanna build something simple, which requires a library? Boom, mostly results into error from pip. Try to install numpy as a beginner, and get:



Thought that's the beginning? Welcome to the infamous "import imp" line:
Think you can resolve that? Here you go:
That, of course, are just some examples. I'd rather use Assembly than switch back to python, because it was a pain to even load up the language without burning my CPU down.
Python is certainly my favorite language for pretty much every project, large or small. I've been using it very effectively as my primary language for over 20 years.
However, I find that I agree with much of the criticisms of python.
The two main weaknesses of python are:
This is a horrible combination.
The problem is that people can quickly become quite productive with python before gaining an understanding of the essence of the language, and before learning what does and doesn't work.
For a project to be a success it is extremely important to have expert python engineers on the team, and make sure there is a policy of code review on all commits. Code review is the most important, because most bad habits in python would be spotted by an extra pair of eyes.
Experience in other languages doesn't necessarily help. Python is unique. Many of the most common pitfalls in python are indeed considered best practice in other languages.
A couple examples of this:
Java makes a clear distinction between data attributes and methods. If you think you need encapsulation, you must hide data attributes and use getters and setters to manipulate them indirectly. Otherwise when you change the implementation, you will have a huge refactoring task in front of you.
In python, there is absolutely no reason whatsoever to preemptively wrap your data attributes in getters and setters. You just use the attributes. Change them to properties later if it becomes necessary. Python's flexibility allows you to do this seamlessly without any refactoring outside the class being modified. In python, your best bet is to keeps things simple and concise.
In one project I found over 3000 lines of code specifically dedicated to completely unnecessary encapsulation of ordinary attributes. There was no benefit, and it made the resulting code brittle and slow.
In C++ any medium to large project has a build as a centerpiece. The model is that you have source code which you process to create something that you run. In python you basically just run the source code. Sure it's compiled to bytecode, but that's a hidden caching operation that you usually don't need to think about. And yes, in many cases you have some kind of deployment, but it need not be complicated, that shouldn't significantly impact how you think about the architecture.
So there was this project involving a million or so lines of code. The architecture involved an ad hoc package manager that would concatenate a bunch of python modules into various larger files, encrypt the result, and then use a messy import hook implementation that would load these monstrosities. The order in which things got imported was critical because lots of code would execute on import. When it came time to upgrade to python3, a nightmare was at hand.
On the other hand, I've seen plenty of beauty in python projects. The most successful always involved keeping code quality as a high priority, ubiquitous unit testing, and a high level of collaboration including code review.
Python is kinda all over the place syntax-wise in my opinion. I like languages that make use of parentheses and braces and that sort of thing. Python was actually where I started learning too.
For me, clarity over cleverness is the primary feature of a programming language. I favor object oriented languages because OO matches how I think about the world (and with Python OO is a crude afterthought).
More reasons I find python confusing and inelegant:
The syntax for lambdas in python is very clunky. Only a comma indicates where the block ends, and it has to fit on one line.
A class name is sometimes required as a function parameter in order to call a base class.
Python users often abbreviate unnecessarily, making it hard to know exactly what modules you’re including
There are some magic built in global functions, like len() which should be member functions of the relevant classes.
Standard libraries are also inconsistent in their naming conventions, like unittest which uses setUp instead of set_up
Decorators like @staticmethod are used to retrofit common language features.
A python dictionary (a very common data structure) has odd initialization semantics.
Here are code examples of the reasons why I hate python.
I like Python for prototypes and small batch.
I would like it more, but too many coders seem to assume that python means that you have permission to write bad code.
So my grief isn't against python, but against bad engineering practices.
The good thing about python is that any idiot can use it.
The bad thing about python is that any idiot can use it.
Ahah, true !
I oftenlty talk about Python as "Easy to learn, hard to master"
Easy to read?!
Did you just say python is easy to read?!
Are you joking?!
Python is the most unreadable language i have encountered!
(i mainly program in c++ in VS)
If we're not counting "Brainfuck" that is.
Python is just confusing.
Variables have no defined types, you can write code outside functions, it doesn't use curly brackets, so it relies solely on insets. Also the default ide is more than shit. No line numbers, not even auto correction suggestions or anything like intellisense.
I once had to program in python because of a certain Library Wrapper. After two hours of missing my dearest c++, i just resorted to call my script.py via the system() function in c++ storing the return value in a textfile...
Over all 1/10.
And this one point is just because i love how easily you can import libraries via pip3
The types of variables are constrained by the operations you use in the function definition, and of course its name. For example,
def myadd(a, b):
----return a + b
Rather than thinking about a and b as numbers [isinstance(a, Number)], think of them as variables that have the +(add) operator i.e: ['add' in a.class or hasattr(a, 'add')]. Another thing you can do is look at its callers, or setting a break point inside the function.
I don't know a line of Python. But I have been using undergraduate students---hundreds of undergraduates--to write research analysis code for me since 2013. Most of them are pretty darn good---I have high standards for entry into my research class.
Most of them have learned Python because that's what our university teaches as a first programming language.
So, you ask, how can I hate Python if I don't know how to write a single line of it?
Because pretty much every python program ever written by any of my students either doesn't work on another machine in the same cluster that's supposed to be configured identically, or stops working on the VERY SAME machine within a few months when some minor version number changes. Really, people. Does it really matter whether I'm using Python 3.6.4 or 3.6.5? REALLY? The third digit in the version number changes, and the code stops working?
I've been told by the local experts, "oh, it's easy to write portable code in Python". They must be using some alien definition of "easy" that's not found in the dictionary, because this is a recurring problem. Every quarter, every time I try to re-run some code that was written more than a few months ago, it fails. Traceback errors, missing library errors...
This is completely unacceptable. I have written code in 1991 that still runs. (In C. And Bourne Shell. And awk, if you must know.) Now I'm not trying to say that C or Bourne Shell or awk or f77 are better....but I'm saying that if students in their 3rd or 4th year of a Computer Science program at a decent university still can't figure out how to write code that lasts longer than a month... there is something seriously wrong.
My only saving grace is that I continue to recruit new undergrads every year, and they are able to "fix" the code.... that quarter. But pretty much guaranteed it'll die again.
This is why I hate Python. In fact, it is rare that I speak of the language without the F-word---usually in ALL CAPS---as a prefix. All my students know I hate Python, but I continue to let them use it because if I want them to do work with me, I have no choice.
Is it easy to learn? Probably. Easy to master? Clearly not. Easy to maintain? HELL NO. (Less politely... give me a f*cking break, no friggin' way.)
That's my 5 years of experience.
End of rant.
Refactoring is a nightmare. Add an extra argument to a function and expect to get errors in the distant future when an infrequent condition is met during execution and some remote part of the code calling the function with the old argument list will break.
If you add the extra argument as an optional it will work nice much of the time.
def func1(a, b, extra = 5):
----func2(5, a+b, extra=extra)
Doctests are good documentation and easy to write (just copy and paste your console session), but its true its hard to exercise EVERY code path. You can also automatically create some doctests by doing using a createTest decorator i.e: f = createTest(f) for all f in user defined modules, but no guarantees.
As long as your not doing some complex polymorphism, pylinters can catch many although not all errors. I believe some of them use "Type Inference".
I wonder how do Smalltalk and Lisp solve this problem? Did they go the Erlang route and reload code on errors?