I started coding with Basic (on the Commodore 64, of course), but I consider myself mostly a C++ programmer. That’s the language I used throughout my time as university student and that I still use for point cloud processing and most things that are runtime-critical. There have of course been detours like Matlab, PHP, Fortran, and VBA, and C# has played an important role in the last 10 years and is my go-to language for Windows GUI programs. But there is no denying that Python has become a hugely popular and powerful programming language, so even I had to start using it. Here is my opinion from a C/C++/C# developer’s perspective.
So many packages
The main benefit to me are the many packages available for Python, which can most of the time be installed with a simple pip install. From simple stuff to advanced machine learning and neural network packages, there’s something for everyone here, and getting it to run is usually much easier than having to compile and link libraries for C++. NumPy and Pandas offer functionality that I would have loved to have had 20 years ago.
No need to compile
Talking about compiling, there’s no need to do so with Python as it is an interpreted language. Just open your IDE (Visual Studio Code is a popular choice), write some code, and hit F5. You can even use a simple text editor and run things from the command line, or use Jupyter to write and run code in a web browser.
Multi-platform
Being interpreted also means that Python is inherently multi-platform. No need to recompile stuff, as long as all needed packages are installed you can simply run the same code under both Windows and Linux (and even Mac OS, if you are so inclined).
Built-in data types
The Standard Template Library has made life a bit easier for us C++ folks, but even then, there’s not exactly an abundance of data types included. Python offers easy-to-use things like lists and dictionaries that can make life much easier than, as in the old C days, being limited to structures and arrays.
Multiple return values
Matlab has these, and I’m glad that Python does, too. Not being limited to a single return value means no messing about with pointers and call-by-reference. What’s in a function call goes in, what goes out is a return value.
Scripting
Being popular and interpreted has made Python a popular choice as scripting language for applications like QGIS. As these usually simply call an installed Python interpreter, you can install all packages that you need. If implemented and documented well (looking at you, Allplan), having Python as scripting language is great and certainly preferable to some Javascript dialect.
And why it sucks
Slow for loops
For someone who grew up with a choice between for and while, and who routinely uses a properly placed #pragma omp parallel for to speed things up, it can be difficult to work around how slow for loops are in Python. Some of this can be mitigated by using NumPy and Pandas functions that operate on all rows (and use compiled C code in the background), but there are cases when this is difficult or even impossible.
Easy to write unreadable code
Python code is often called easy to read, but with constructs like Lambda functions and for … in … if not .. make it possible to write code that is not exactly easy to understand.
Where are my curly brackets?
Python structures code only by indentations (tabs or spaces, never both in the same file!). This is cool for the crowd who thinks that it saves them two characters to type (it’s only one, as there’s a : required after for, if, etc.), but it can sometimes make it difficult to identify the end of code blocks.
Syntax now always as straightforward as one might think
This is maybe most evident in the Python range statement. range(0,50) runs from 0 to 49, not 50. This probably done to help C coders who have for(i=0;i<50;i++) programmed into their muscle memory, but it is not evident by looking at the command. Another thing that bugs my is how, when working with classes, one has to give self as first argument in each method definition, but you don’t actually pass the instance as argument when you call the method. This looks to me like object orientation was added as an afterthought, and not in a pretty manner.
Type checking only at runtime
A disadvantage of not compiling is that type checks occur at runtime. So simple programming mistakes like trying to add an integer to a string will only be caught at runtime, possibly at the end of a lengthy program run. This is also true for other syntax errors that are only caught once program execution reaches them.
Distributing programs can be a mess
Lots of packages means lots of trouble. Incompatible versions of Python interpreters and packages have created the need for things like virtual environments, and getting someone else’s code to run may involve a lengthy fight with pip and conda until all dependencies are met. Where with C++ it’s up to the developer to package all required DLLs, with Python this is often left to the end user.
Horses for courses
What this means is that, in my opinion, Python is not the one language to rule them all. I think it is best used for smaller programs that get most of their functionality from external packages, and as scripting language for applications. For Windows GUI applications C# is hard to beat (and as the .Net framework is installed on every Windows system, programs will often be only a few hundred kilobytes that need to be distributed), and for runtime-critical stuff, I’m happy to stick to C++. Thanks to Boost, many things that one would have had to program with pure C or even older C++ versions (like proper string handling and dealing with file systems) are now readily available on multiple platforms. I also regularly encounter libraries that only have a C or C++ interface, and C/C++, along with Fortran, is still the predominant language for High Performance Computing applications.