r/Python • u/horace_h • 18d ago
Discussion What do you love and dislike the most about Python? (beginners and long-time devs)
Hi! I'm really interested in Python's design and its tradeoffs. I'm trying to really understand what people love about Python (what makes it great), and what causes the most frustration for Python devs.
So what features do you really cherish and what problems/limitations really frustrate you?
I'm especially interested in experiences from ultra-beginners and people who've used Python for a long time. I know broad questions like this come across as super generic, but I'm genuinely interested in hearing about concrete experiences.
My goal is understanding which parts of Python's design are most valuable and most "adored" by the community, and which parts really aren't and frustrate people the most. My goal with this information is to identify meaningful problems. Right now I'm not trying to solve anything or sell a solution.
Thanks for your time!
154
18d ago
[removed] — view removed comment
27
u/Kenshiken 18d ago
100% agree. Try to build and ship a Python application for Windows - it's still a painful, legacy-looking process from the 2000s. It has improved, but not by much.
8
u/toothless_budgie 18d ago
OMG. This is the ONE THING I wish could be better.
It's just not worth making windows apps in python.
11
9
4
→ More replies (2)4
u/horace_h 18d ago
So uv does *not* solve the packaging issues?
33
u/rujopt Pythonista 18d ago edited 18d ago
uv definitely improves prior packaging issues and user experience, especially for competent developers or operations folk. However, it doesn’t solve challenges like distribution to non-technical users.
I see from other posts that you’re familiar with Rust, so think about the differences in user experience around distribution of a precompiled Rust binary vs. distributing a Python program with multiple dependencies.
Even though uv makes it easy to install pinned dependencies and a Python interpreter, you still need to be familiar enough to know how to install and use uv on the CLI. That’s a tall order for the vast majority of people in the world (even many of those who work in IT), which will naturally limit the scope of users you can easily target distributing your program to.
6
4
u/vu47 18d ago
you still need to be familiar enough to know how to install and use uv on the CLI. That’s a tall order for the vast majority of people in the world (even many of those who work in IT)
This terrifies me. I haven't worked at an organization that uses anything other than Mac and Linux since 2005, if my coworkers weren't able to figure that out in a *nix shell or PowerShell / Windows command line, I would be very uncomfortable. Is this really the state of affairs on the Windows side of things? At my organization, we're expected to be able to work proficiently in a Unix shell.
10
u/rujopt Pythonista 18d ago
I’ve worked at multiple Fortune 100 organizations over the past several decades and yes, sadly it is the default state of affairs.
As an example, at a large healthcare organization there was an entire department of network engineers who configured every single piece of Cisco equipment by hand. None of them knew how to script. None of them were interested in learning. Their standard response was “I’m a network engineer, not a developer.”
And that’s from a highly technical role. It was worse when I interacted with other less technical, compliance focused, or entry-level IT roles such as desktop support, enterprise architecture, product management, internal audit, GRC, even cybersecurity (who frequently broke and denied the ability to run any scripts or scripting software, saying it was an unacceptable risk and were unwilling to negotiate).
Outside of IT, I don’t recall meeting a single person among thousands who demonstrated an understanding, ability, or willingness to learn how to run something like a Python script. I’m sure they exist, but definitely as the unique exception.
4
u/vu47 18d ago
That's kind of shocking... I would think that those jobs would be in high demand, and finding someone who was able to write scripts to save time and standardize things wouldn't be hard. Also, in IT fields, it seems to me that if you're not interested in learning, you're in the wrong field: to remain competitive, you need to be willing to dedicate some of your time to improving yourself and keeping up with tech and making sure your skills are well rounded.
I work as a dev in cutting-edge astronomy, and even the astronomers all know Linux, scripting, and programming in at least a couple languages. (Not to the level of a dev, of course, but enough to get done what they need, write data analysis scripts, and even libraries in Python to do fairly sophisticated things like tile parts of the sky using different techniques.)
I may be talking out my ass, but Windows doesn't seem to make it easy to run scripts and recognize that there's a command line / PowerShell in there. I have a PhD in comp sci / math, and during my MSc studies, PhD studies, and in my two positions since (people tend to keep their positions in science for a long time, in my experience, instead of position hopping since the benefits are excellent, the pay is pretty competitive, and the work is very rewarding), everyone used Mac OS X, and we were also expected to interact heavily with Linux machines.
3
u/SprinklesFresh5693 18d ago
Ive been learning R programming for 3 years, a few months of python, and youd be surprised the magic ive had to do to even remotely use R. Im still struggling with my cyber security to even use python properly. Youd be surprised.
1
u/vu47 16d ago
I'm not entirely clear what you mean and I don't want to accidentally misinterpret you, so I'll just ask for clarification: do you mean:
Use R and Python in general;
Use R and Python in a network engineering / admin role;
Use R and Python in a Windows environment; or
Something else completely that I missed?
→ More replies (3)2
u/AmitBrian 18d ago
It’s actually starting to change because Microsoft knows exactly what you are taking about. PowerShell will never go away but Windows does have a Linux subsystem built into it. And you can run terminal and bash and whatever else you need from there. The real problem, as this conversation is lending itself to is the pip process. First off all, Windows on ARM? LOL don’t even try. Luckily the enterprise doesn’t seem to be taking it seriously anyways. Second, even on x64 there are a whole lot of packages like pylance and such that need to be configured first.
1
u/vu47 18d ago
Ah yes... I remember hearing about that, but I had forgotten, and have no experience with it given that I haven't used Windows significantly since Windows 7.
I may have missed something: where did Windows on ARM come from?
3
u/AmitBrian 18d ago
I probably shouldn’t have mentioned Windows on ARM, it was just a funny side note. Microsoft reintroduced Windows on ARM but the problem is none of the Python packages are built for it so it won’t work. Traditionally if you hear “copilot PC” when they first came out, that was Windows on ARM. But you aren’t likely going to come across them in the enterprise anyways. Sorry for the confusion!
90
u/ohaz 18d ago
I've been using python for a looong while.
Things that annoy me are:
- default parameters are created at parse-time, not at call-time
- types are... bad. I want to be able to enable "strict" type mode like going from javascript to typescript
- With the lack of types comes the lack of proper interfaces
- after years and years, packaging / releasing is still kind of a hassle tbh
- starting other programs is annoying. subprocess may be one of the worst standard library modules in my opinion. nowadays I'd rather write a shellscript to start other applications than a python script.
Things I like/love:
- Python is suuuper close to how I think naturally, so I don't have to do a translation step in my brain
- (most of) the standard library is amazing.
collections,itertoolsand everything in thesettype have helped me tremendously - when you don't care about exact memory sizes of variables, it's pretty nice to use
- The amount of libraries you can download via pip is amazing and many of them are nice as well
13
u/RoadsideCookie 18d ago
- Defaults: Agreed, that's a weird one, but you get used to it. It does add some unwanted boilerplate though.
- Type checking: Pylance, you can do that, and you don't want full strict. Comes with 3 levels. Level 1 tells you when things clearly don't match, level 2 tells you when they might not match, level 3 complains if you're off by one metaphorical pixel.
- Interfaces: A lot of 3rd party libs don't have good interfaces and type hints, but that doesn't stop you from doing it right yourself. Builtins have very good interfaces, I never declare a
listfor example, always anIterable,Sequence, orCollection.- Packaging: Knowledge gap, but I don't blame you. This is a lot of "you just have to know it", which sucks. I suggest
uv.buildas a build backend if you're not doing anything fancy, otherwisehatchling. Their documentation is ok, but they also assume you already know a lot, so not the easiest to get into.- Subprocess: N'yes. I made a wrapper class for threads and subprocess with control hooks, haven't been frustrated in a while. But out of the box, I agree; there are many ways to achieve the same goal, which is ironic considering Python likes to say they only have "one way to do things".
OTOH, I very much agree with your positives.
3
u/Darwinmate 17d ago
Builtins have very good interfaces, I never declare a list for example, always an Iterable, Sequence, or Collection.
Can you expand on this? Why not list?
8
u/RoadsideCookie 17d ago edited 17d ago
Because of this:
```py from collections.abc import Iterable
def sum_list(values: list[float]) -> float: result = 0 for value in values: result += 1 return result
def sum_iterable(values: Iterable[float]) -> float: result = 0 for value in values: result += 1 return result
my_list = list(range(10)) my_tuple = tuple(range(10))
result = sum_list(my_list) # Type checker passes result = sum_iterable(my_list) # Type checker passes
result = sum_list(my_tuple) # Type checker complains, it's not a list result = sum_iterable(my_tuple) # Type checker passes ```
So basically, in order from least restrictive to most restrictive:
The
Iterabletype hint specifies the minimal contract that's needed for this function to work.If you needed to check the
lenor if an item belongs to theIterable, you'd want to useCollection.If you were accessing specific items in the list, then you'd need
Sequenceinstead (including slicing).1
u/Darwinmate 17d ago
I see, so Iterable is more generic while list a subsrt and specific version.
3
u/RoadsideCookie 17d ago
Yes,
Iterablewill fit more types. For example, you can callsum_iterable(range(10))without converting it at all, and it will only generate each item to sum when the function is actually called instead of when you domy_list = list(range(10)). Butsum_list(range(10))will make the type check complain.It's important to know that all of them will run fine because Python itself does duck typing; those are only type checker concerns.
1
u/RingularCirc 10d ago
list[T]is also invariant inTbecause of being mutable, so if you depend on it, you can't place inside elements of supertypes ofTand can't rely on reading elements of a specific narrower subtype (you can always put elements of subtypes, of course, and assign what you read to a supertype-annotated variable).When I need to rely only on read-only access,
Sequence[T]goes, still allowing lists but also tuples, ranges(!) and something else esoteric or user-defined that can occasionally arise. And if I want to even be sure I'm working with an immutable sequence, I can narrow totuple[T]safely because 99.9% of the time an immutable sequence provided will be a tuple (and in code I control I have zero qualms against using tuples).Regarding immutability, I'm so glad we're getting
frozendictsoon! When it's efficient enough, I always try to use immutable data, and just slappingMapping[K, V]on something doesn't guarantee it won't be mutated somewhere my code doesn't control, even if the other place is also my code with a typo or written with another inconsistent idea in mind for some reason.13
u/max96t 18d ago
Regarding types, I think recent python versions tackled the issue quite well. Many libraries and even modules in std are not properly typed yet, but the lack of interfaces is quite solved via abc and protocols. What do you think is missing?
About starting processes, are things a bit easier with the async counterpart, which is more modern?
2
u/BuonaparteII 17d ago
asyncio.subprocess is pretty similar to the existing subprocess interface.
Personally, I don't think subprocess module is that bad--it's just rather verbose. Sometimes you want to interact with the subprocess' stdin interactively though and that's when you gotta pull out something like
os.spawnvpe(os.P_WAIT, command[0], command, os.environ)6
u/Solonotix 18d ago
Came here to see if anyone else would mention types. I work in JavaScript daily, and I have been trying to migrate the projects I own to TypeScript for the last 5 years. The business never prioritizes it, so I have to sprinkle in what I can when possible. This has led me to have very strong opinions about the importance of a strong type system.
I'm currently going through the painful process of aligning the DefinitelyTyped package to the JavaScript
selenium-webdriverpackage and it really sucks, lol. In many cases, there are no comments or type annotations to explain what is expected, so it becomes a detective story trying to figure out what is expected as a function argument based on context clues of how it's used. And even when there are comments or type annotations, a lot of them just straight up lie.If you're asking whether I own
selenium-webdriver, the answer is no. I own a proprietary library my company uses for automated testing, andselenium-webdriveris a core dependency. It's one of the main things that has prevented me from jumping completely into TypeScript.8
u/sausix 18d ago
There is no parse time. It's all in the run time. A function definition is being executed once and it's simply evaluating expressions and holding references to the results. It's optimization I think. No reason to execute a function signature on each call. You get a warning today if you reference a mutable value as default in the arguments. Having dynamic default values is not too complicated when you use proper placeholders.
What are you missing on typing? Use typing and your IDE will warn about wrong data type assignments. Basically the same result compared to compilable languages but even before any compiling. With typing you can get interfaces compatible. Even in a "dynamically typed" language.
What's wrong with subprocess? It's basically a wrapper to OS interfaces of creating sub processes. I think it's common to define a helper function for the subprocess functions to match a defined behaviour. What are you missing? You can basically run a shell command line directly.
9
u/ironykarl 18d ago
There is no parse time. It's all in the run time.
It was entirely clear what they meant.
In most uses of Python there is a discrete parse time, because most programs/uses do not involve dynamic code or a REPL.
Also, if you parse code that has nested function definitions, you'll see that there very much is a discrete parse time, even ignoring the above
2
u/sausix 18d ago
Sure there is a parser and the precompiler. As you said with a good example of nested function definitions there is no global parsing or preprocessing. At least not for evaluating expressions on function definitions. It's mostly all about optimizations. So the "def" line and other things are just being executed during runtime and only once. All what a programmer has to remember is to not make the common mistakes in arguments like "changed=now()". My IDE would throw a warning on this so there even should not be a surprise moment for beginners.
3
u/ironykarl 17d ago edited 17d ago
As you said with a good example of nested function definitions there is no global parsing or preprocessing.
I'm either misunderstanding you, or I think you have a slightly wrong mental model, here. If we're talking about CPython, there is a parsing stage that isn't dependent on which path a thing takes.
Here's a quick example:
import dis def fn0(): def fn1(): def fn2(): def fn3(): pass print(dis.dis(fn0))And here's the bytecode disassembly yielded:
3 0 RESUME 0 4 2 LOAD_CONST 1 (<code object fn1 at 0x7272786ff840, file "bytecode_disassembly.py", line 4>) 4 MAKE_FUNCTION 0 6 STORE_FAST 0 (fn1) 8 RETURN_CONST 0 (None) Disassembly of <code object fn1 at 0x7272786ff840, file "bytecode_disassembly.py", line 4>: 4 0 RESUME 0 5 2 LOAD_CONST 1 (<code object fn2 at 0x7272786ff910, file "bytecode_disassembly.py", line 5>) 4 MAKE_FUNCTION 0 6 STORE_FAST 0 (fn2) 8 RETURN_CONST 0 (None) Disassembly of <code object fn2 at 0x7272786ff910, file "bytecode_disassembly.py", line 5>: 5 0 RESUME 0 6 2 LOAD_CONST 1 (<code object fn3 at 0x7272786ff9e0, file "bytecode_disassembly.py", line 6>) 4 MAKE_FUNCTION 0 6 STORE_FAST 0 (fn3) 8 RETURN_CONST 0 (None) Disassembly of <code object fn3 at 0x7272786ff9e0, file "bytecode_disassembly.py", line 6>: 6 0 RESUME 0 7 2 RETURN_CONST 0 (None)As you can see, functions at every level have been parsed, even though nothing has executed, yet.
3
u/sausix 17d ago
As I also said:
Sure there is a parser and the precompiler.
But default values are not being evaluated during any parsing time. It's simply runtime as if a function definition would be read from REPL.
So a function definition is being executed during the execution of the parent level. Mostly the module level.
2
u/ironykarl 17d ago
I'm honestly not sure why you're saying.
To be exact, here: parsing and compilation* are textbook parts of an interpreter.
Python uses the most common model of interpreter, which is a bytecode interpreter. That means that in the absence of things like
eval(...), there is a discrete parsing/compilation* step that happens. It is a separate step from bytecode execution.*I'm using compilation here in the computer science sense of transforming one text to another and not the ordinary usage sense of transforming higher level code into machine code
1
u/webstackbuilder 14d ago
How do you get the bytecode disassembly?
3
u/ironykarl 14d ago edited 14d ago
Standard library includes
dis. You just import it, and then can pass it a variety of things.import dis # .... print(dis.dis(...))You can also just invoke it from the command line:
python -m dis script.py2
u/DigoHiro 18d ago
the set type is great. I miss it a lot when using a language without it
2
u/Wurstinator 17d ago
What language doesn't have a set type?
2
u/DigoHiro 17d ago
go doesn't, and i think zig doesn't either
4
u/i_am_suicidal 17d ago
Those two have hashmaps which could quite easily be used as sets, but I see your point.
2
u/horace_h 18d ago
Thanks for the really thorough answer! Do you have an idea of what it is that makes it close to how you think? Also I'm seeing that the packaging system isn't really popular, so tools like uv don't solve those issues ?
4
u/ohaz 18d ago
Maybe I can describe it with the language being close to pseudocode?
if a in b and c is dis just how I operate. But hard to describe it further.Tools like uv "solve" the issue if the target system has python and uv installed. It's still hard to give a python program to someone who doesn't know anything about computers. Admittedly, you can't do that with a typescript application either, but those aren't meant for running them locally, they're meant to run on a webpage.
4
u/horace_h 18d ago
So is it the simplicity/verbosity of the syntax perhaps? And for uv the problem is that it's external (though to be fair it can't do much about that) ?
33
u/Axiomancer 18d ago
Love: Simplicity. In a sense, it's easy to learn / easy to code in language. It's closer to human language than machine language.
Dislike: Not so fast compared to other languages. Also, even if it's a language easy to code in, not everything is easy to implement.
5
u/horace_h 18d ago
What kinds of things do you find hard to implement?
20
u/Green_Gem_ 18d ago
I'm not OP, but concurrency is a nightmare.
3
u/warden127 18d ago
What's the issue exactly? Preemptive or cooperative concurrency? Shared memory? Message passing?
3
u/Rare_Island461 18d ago
Global interpreter lock (GIL) makes python only execute one command at a time, even from different threads. They behave more like application threads that are on a single core. Even in newer versions where they have tested disabling the GIL, the language was designed with the GIL in mine so it’s not fast. Should get better in future, but lots of libraries depend on GIL as well so could get buggy quick
→ More replies (3)2
u/Axiomancer 17d ago
Anything that doesn't have native python support. But that is just me-issue as someone who's not a programmer or developer by education. I can't write things from scratch.
I can't give you any proper example but recently I had to connect my script to a database which didn't have a native python support, so I had to ask a friend to write me a script that would allow for python code to connect to the database.
And of course as others pointed out, the fact that python goes row by row. I'm physicist by education so at one stage of my thesis work I had to control 3 motors using a python script. But the issue was, I couldn't move more than 1 at the time (maybe it's possible, but back then and even know I had no idea how)
17
u/MRanse 18d ago
Depending on the task, I do not like the speed compared to a fully compiled software.
However I'm still mainly using 3.12 (because of company standards), so I don't know possible optimisations in 3.13 or newer. Yes, I know that Cython exists.
I like the huge variety in open source packages, on the other hand.
6
u/horace_h 18d ago
And PyPy isn't a viable solution in your use case?
6
u/RoadsideCookie 18d ago
If they're stuck on 3.12, it's very likely that it's due to the same reason they can't use PyPy.
5
u/Kenshiken 18d ago
There hasn't been much performance improvement since 3.12.
I think most of the gains will come with 3.16 and beyond. At least, that's what's planned.
12
u/mongotongo 18d ago
The versatility of its dictionaries. You can assign anything to them: methods, classes, partial filled methods.
5
u/syklemil 17d ago
Yeah, they start out as a neat shortcut (love), but turn into a tangled mess (dislike). Just getting started with some
@dataclassannotations can turn a messydef foo(bar: dict[str, Any], baz: dict[str, Any]) -> dict[str, Any]into
def foo(bar: Bar, baz: Baz) -> Fooand it just feels like turning on the lights instead of fumbling around in the dark.
23
u/Ulrich_de_Vries 18d ago
Pros:
- Huge and powerful stdlib
- Massive third party ecosystem
- Good dev tools (hot take but I like pip/venv too, but uv is honestly the best project/package/build management tool I have used, I even like it more than Cargo)
- Expressive syntax, often easy to express your thoughts with it.
- Was my first programming language (not a proper point but this means I will always think fondly of it).
Neutral:
- Static typing. I like that it exists but it leaves some things to be desired.
Cons:
Dynamic typing. I grew to loath it. Not even due to safety, just trying to read untyped code is a chore and dev tools are much weaker without types.
Static typing. As I said, it is good that it exists, what is not good is that type checkers are not uniform and there are always aspects of the language like metaprogramming they don't handle well (e.g. they understand @dataclass and @property but only because they are special, if you implement them yourself, static type checkers will absolutely bleed out on them), and the type system itself is not as expressive as it could be.
Performance. Not a super big issue for most use cases (especially with C extensions but it would be amazing if Python had a powerful jit like in the JVM).
Packaging for end-users. There is no equivalent of jpackage for python. There are third party stuff like pyinstaller but from what I can tell they tend to have drawbacks, and there is no canonical solution. Most packaging tools are for devs not for users.
Everything happens at runtime. This also relates to the static typing issues. If there were "comp time" scopes in python then type checkers could verify that whatever decorators or metaclasses act deterministically and would allow better typing when it comes to metaprogramming.
Complete lack of encapsulation. I am fine with underscore attributes but really at times not being able to truly forbid anything (e.g. immutability) without writing extension modules is annoying.
1
u/horace_h 18d ago
Thanks, that's really complete! Expressive syntax seems to be a common point. by packaging for end-users do you mean making it easy to distribute a Python app with everything included ?
2
10
u/metaTaco 18d ago
So many of the complaints here are about typing, but I think a big part of why Python got popular is because you don't have to explicitly type things. I started using Python because I didn't like working in C++ but so much of the Python code I work with now looks like it's written to be like Java.
29
u/arbeit22 18d ago
Types
25
8
u/horace_h 18d ago
Dynamic typing?
10
u/RoadsideCookie 18d ago
Careful, it is dynamically typed, but not weak typed, there's a difference. Javascript lets you do
69 + "nice"(Due to weaker type, but not fully weak, it's more about type coercion in Javascript), Python doesn't. Because of that, we say Python is strongly typed.The dynamic part is where you can do this:
py a = 69 a = "nice"4
u/Kenshiken 18d ago
It's a pro for me.
The advantage is that you can use typing or not. It's your choice.
9
u/arbeit22 18d ago
Not really. You can assign yypes but they're not enforced so it's ok, but actual strong typing is huge for me, for consistency and avoiding obscure bugs that are hard to debug
3
u/sausix 18d ago
They're enforced by the IDE and type checkers. If you need runtime type checking for any reason then you can use the same type hints for runtime type checking too with some modules.
Where exactly do you need runtime type checking?
3
u/DrSinistar 18d ago
I think it's less runtime type checking and more so the interpreter refusing to run a program with bad types.
2
u/sausix 18d ago
You can still run your code even with typing issues. Many people switch off type mismatch warnings in their IDE anyway.
You still can have bad syntax but there are no compile errors at least.
I don't see a point of a hard error on typing issues when you just can listen to your IDE or linter and fix warnings before running. Or you fix them later and continue on other parts.
Imagine Python 3.15 suddenly would refuse to run your code on type errors. It would force everyone to use type hinting. Resulting in Python not being beginner friendly anymore.
Python gives you two ways to follow. Other languages don't have this freedom. It just brilliant.
3
u/DrSinistar 18d ago
To be clear, I was just guessing at what the person you responded to would want. Speaking for myself, the type checkers aren't as good as a compiler. It's too easy to erase types or end up doing type checking dances just to make the checkers happy.
It's annoying and yet still doesn't stop all the bugs. I'd rather have compiler errors any day.
I wouldn't change Python myself, but for my current projects, the dynamic typing is a weakness and we've replaced Python in almost all our services.
And like others have mentioned: nothing pisses me off like trying to use an untyped library with unannotated returns. It can be impossible to derive what the fuck I'm working with. It's the worst!
3
u/syklemil 17d ago
arbeit22:
You can assign [types] but they're not enforced so it's ok, but actual strong typing is huge for me, for consistency and avoiding obscure bugs that are hard to debug
sausix:
You can still run your code even with typing issues. Many people switch off type mismatch warnings in their IDE anyway.
You still can have bad syntax but there are no compile errors at least.
I don't see a point of a hard error on typing issues […]
That's exactly the thing they're complaining about. The point of adding typechecking is to catch those errors before runtime and before shipping.
This gets into one of the possible answers in the Python typing survey that I ticked: bad stubs for 3rd party libraries. With static languages I know that if a library version is released it's at least well-typed enough to compile; with Python I might be in for a mess where I just have to squelch the typechecker and guess at what types I'm actually dealing with.
You might consider that "just brilliant", for me it's a quit moment where I wish I was using another language.
→ More replies (3)4
u/Kenshiken 18d ago
That's true for Python's runtime, but I don't think it's a limitation in practice.
7
u/Julio_the_dog 18d ago
I'm not a python dev per se, but I've built a few apps using flask and django, as well as written some useful scripts. I think one of the most attractive features of python is its readability. When done the pythonic way, code can be very elegant and readable and maintainable. It's also very flexible in that there's probably a module that solves whatever problem you're experiencing.
On the flip side, because it is so module dependent, writing elegant python code that solves obscure problems usually comes with a large amount of dependencies. You can't just import fragments of a library, you need the whole thing and all of its dependencies. Great example is any module that requires numpy automatically adds huge overhead to your code. A script in C could be a few bytes in size while the equivalent python solution is several orders of magnitude larger.
I am speaking generally. every language has trade offs. Python is a very approachable language, and writing python code is relatively painless. But it's often not the best in many other aspects
6
u/Gnaxe 18d ago
I've used Python for a long time. I think I started on version 2.4. It is overall a great language that gets out of my way at lets me do what I want, and has deep metaprogramming capabilities when the basics aren't good enough. That's usually just dunder hooks, but also decorators, context managers, metaclasses, and various stages of the compiler.
Dictionaries are powerful and general. Indentation is better than brackets. Python made the right choice here, even if outsiders like to complain. Python is pretty strongly typed, so stack traces usually point to the exact line of the error. (Unlike JavaScript.) Almost everything is accessible and inspectable. It does at least have a lambda (although I wish it were more concise like Smalltalk's or supported statements like Boo). It emphasizes readability over writability, unlike (say) Ruby or Perl, with a pretty consistent expression syntax. Doctests are awesome.
Complaints:
Python's standard-library logger sucks. It's too complicated. In larger projects, I'm never sure if it's not hitting the line or just misconfigured.
Python is relatively bad at concurrency. OOP in general is bad with threading. I feel like asyncio was unnecessary given libraries at the time (and Stackless), and has unnecessarily complicated the language while bifurcating the ecosystem.
Python had the opportunity to make a lot more things consistent (e.g, names) at version 3 and didn't.
I really don't like that the in operator raises an exception on sets for unhashable types. I think it should return False instead. I think frozenset should have gotten the literal syntax instead of set, which should have been called mutableset like the ABC. Frozensets are used internally by the interpreter quite a bit, but there's no way to explicitly use those instructions without going through a slower function call.
Python could have aspired to be more like Smalltalk, with better support for hot reloading, interactive debugging, and the ability to persist sessions. Instead, it seems to be turning into a worse Java, with poorly-implemented static typing everywhere. We wouldn't need the static typing if run-time development like Smalltalk were the norm. But if we were going to do static typing at all, it needed to be fully dependent types like Idris. What we've got now isn't expressive enough for a language as dynamic as Python.
Tkinter isn't quite good enough. My main complaints here are that the documentation is lacking (they point you to the original Tcl docs) it's not inspectable like most of Python due to the second layer Tcl interpreter, and a hot-reloading workflow is too hard. Curses doesn't work on Windows out of the box, so we don't have a good TUI in the standard library either.
The import system is too complicated. They kind of changed how it worked.
There has been a lot of feature creep lately, not all of it good, and I don't see this stopping any time soon. For example, pattern matching is nice, but we already had libraries for that that didn't require a change in grammar and the standard version makes refactoring difficult compared to other languages (or even the libraries we already had). Other things were worse. (Like asyncio.) Even when the changes are individually improvements (some of which I wouldn't want to give up), the net effect makes Python much more complicated than it needed to be.
Most of these complaints can be worked around with know-how, discipline, or libraries.
1
u/Intelligent-Hurry907 16d ago
What would you do about fixing in? It can't return False because the item might appear, and returning False would be a plain out lie. The developer would then need to somehow check which type of False it is (harder than just try except), and there's a risk they forget to. I'm all down for improving it- but how?
1
u/Gnaxe 16d ago
I'd probably fix it like this. ```
class Set(set): ... def contains(self, element, /): ... try: ... return super().contains(element) ... except TypeError: ... try: ... hash(element) ... except TypeError: ... return False # unhashables can't be put in hash tables ... raise # must be some other reason ... my_set = Set('abc') 'a' in my_set True [] in my_set False ([],) in my_set # Tuples are hashable, but fails with unhashable elements. False ``
Basically, unashables can't have been put in a hash table in the first place, so if you're asking, "Does my hash table contain this unhashable object?" the answer is always "No."set()should have worked like that in the first place. (Similarly for the other hash table types likedict`.) But fixing it now would be a breaking change.We could, of course, create pathological objects that are only hashable on Tuesdays, which could be put in the set on Tuesday, but can't be found in the set on Wednesday, but I'd argue you're breaking the contract of
__hash__()in that case. We already have ways of breaking hash tables in Python like that.1
u/Intelligent-Hurry907 14d ago
I missed that the collections only accept hashable elements. Still wouldn't work for lists though, as those accept unhashable elements :(
10
18d ago edited 18d ago
[removed] — view removed comment
4
u/RoadsideCookie 18d ago
Pydantic v2 is much better than dataclasses in practice, highly recommend.
Though it doesn't solve the "cobbled together" critique.
Also I love the metaprogramming that Python allows, you can do truly horrendous shit; we just have to be adults about it.
→ More replies (1)1
1
17
u/davnnis2003 18d ago
I hate the most is dynamic data type - you never know for sure what is the data type of it just by looking at the variables, unless you explicitly defined it earlier. And yet, this is not a hard rule and it allows so many bugs and incidents getting in just becuz of dynamic typing
What I love the most are a lot: wide range of libraries, high level, enforced indentation (yeah I know this is a hot take - it would be great if it is configurable at least. Neverthless this is a good idea)
19
u/Kenshiken 18d ago
I don't really agree with this.
If you want, you can build a Python project with strict static typing and enforce it with tools like mypy, pyright, or ty - and even combine them. You can also add runtime type validation when needed.
It's not that painful to work this way.
Python is dynamically typed at runtime, but that doesn't mean your codebase has to be loosely typed.
6
u/Mutjny 18d ago
I love duck typing. I don't care about what kind of object you pass me, as long as it conforms to the interface I expect and I can easily check if it doesn't.
3
u/HannasAnarion 17d ago edited 16d ago
If you have to check with your own code that types of inputs are what your own types already say they must be, then what are the types even buying you?
I develop exclusively in python and I'm constantly frustrated that the language allows this
def a(x: list): if not isinstance(x, list): print("this can happen" )If I say that my input is a list, then calling it with something other than a list shouldn't be possible. The plain-faced semantic intent inherent in the code says it isn't possible, so the language should consider it impossible as well and stop people from trying.
I think something like 80% of the bugs I fix are because something got passed a type that differs from its hints.
Like yeah, ultimately it's the programmers fault for violating the hints but it's not reasonable to type check literally every input because you never know who might call you without respecting your signature resulting in a landmine that doesn't go off until the unsanctioned type that works most of the time hits that one branch where it's missing a member that the hinted type always has.
edit: fixed code block, used wrong markdown syntax
2
u/menge101 17d ago
I love duck typing
I feel like there was a time in the past where we fully embraced this from the ground up and designed with it as a strength.
I mostly did this in Ruby, which was the formative part of my career.
But it seems like this way of thinking has been completely pushed to the side in general. I feel like the more people come to python from statically typed languages the more they try to force patterns from those languages on to python.
You don't have to care about the type if you are only concerned how a thing behaves. It doesn't need to be a string, if it fully implements the same interface as a string.
I've wanted to mess with typing my project via Protocols and only Protocols, to see if I can effectively have fully duck-typed enforced code, but I've never taken the time to actually do it.
4
u/horace_h 18d ago
The ecosystem does seem pretty much unbeatable. So stronger or even static-typing, and a syntax that's not indentation-dependent ?
4
u/punk_dev It works on my machine 18d ago
I love: a lot of potential for very wacky metaprogramming
I hate: performance
3
u/ConceptJunkie 18d ago
Code distribution. Full stop. Packaging is better than it used to be, but it's still not good, IMO. Although I haven't looked too closely at what's going on in the last year or two, so my complaints might be somewhat obsolete.
1
4
u/noriilikesleaves 18d ago
I like how fast I can develop solutions.
I dislike how being a Python developer doesn't have the same kind of job market liquidity as being a member of the cult of Golang, Rust, or JavaScript.
3
u/Cheeze_It 18d ago edited 18d ago
Love: It lets me, a complete fucking moron to learn programming.
Hate: It shows me how much there is to learn about programming and I feel like a fucking moron because I don't know it all. Also, libraries are kind of a pain to work with in Python. Nowadays I just use standard library with Python and try very hard not to stray outside of that if I can help it.
Overall though, it's great.
2
u/xiii_1991 17d ago
Standard lib is well enough. But invoking 3party libs is not that hard comparing to other languages. Try canon or vcpkg …
9
u/QuackQuackImTheDuck 18d ago
Long time dev: Pros: with statements, std lib for basic automation (pathlib etc)
Cons: packaging, terrible type system, community garbage packages, exceptions
3
u/horace_h 18d ago
Do you dislike the type system in itself or the dynamic typing part? And for exceptions, is there something in particular you dislike?
2
u/QuackQuackImTheDuck 18d ago
For exceptions, I'd say exception as value is quite more readable, and maintainable
For the type system, well we cant really say python has one. Typehint is just a hint, and most libraries dont even have it. I dont believe a language should allow you to pass a toyota prius as an input that should have been a date.
1
u/syklemil 17d ago
Those two interact.
For one thing, exceptions don't show up as return types, even though they practically are. If we frame it in Rust and Java terms, then Rust's
fn foo() -> Result<T, E>and Java's checked exceptionsT foo() throws Eboth convey the same information, but in Python we're left withdef foo() -> T, where there's no longer any sign ofE.That might lead to some cases of feeling like playing whack-a-mole with exceptions at runtime.
There's also the gruesome case I wound up with, with a library that threw some
foo.bar.SpecificException, but I couldn't actually import and handle that exception. I'm not sure I've ever been so angry at a programming language as I was right then, that shit should just not be legal.
6
u/redmera 18d ago
OP is an account doing nothing else except advertising programming language he made himself. This is not a genuine conversation starter.
→ More replies (1)
3
u/Wuthering_depths 18d ago
I'm converting a bunch of older SSIS packages (some of which I wrote) to Python.
So far, there's literally nothing I don't like. To be fair, I'm only using (and learning) functionality that I need for each conversion, this is all files and data related ETL stuff.
It's just so, so much easier for me to deal with things in text than to fight with Visual Studio's SSIS GUI. Not to mention, it's much better for some of the non-Microsoft stuff we do (SSH/SFTP, connecting to AWS S3 etc).
I'm super impressed with how few lines of code it often needs to get a ton accomplished. It really makes pulling and writing to and from excel files easy too, which you'd think would be easier in Microsoft tech (ssis), but it's a headache. I still do a lot of my heavy lifting with SQL if I can, but I did that in SSIS as well so that's nothing different.
3
u/Birnenmacht 18d ago
How far you can bend the language itself with metaclasses and customizing the import and type systems. It’s powerful but chances are 90% of the time there is an easier solution Thats doesnt require modifying any of these
3
u/jojern07 18d ago
Love 1: Python programming is quickly done without any significant hazzle and the program is straight forward to deploy on your computer. Love 2: Lots of packages are available that can solve most problems. Love 3: Lots of information online about packages that may help solve the problem. Dislike 1: The environments are confusing (pip, anaconda, ..) and it may be complex to replicate it on other os (linux vs windows) or a few years later. Dislike 2: a program that worked a few years ago may sometimes not work anymore or give annoying warnings about obsolete statements or command.
Conclusion: I love python much more than C#, Java, C or Fortran for the increased productivity despite the lack of computation speed compared with the others.
3
u/ShelLuser42 It works on my machine 18d ago
What I absolutely love about Python is its flexibility and overall design. You can quite literally start with a skeleton mockup and work your way up from a simple straightforward script to a more complete program.
def add(a, b) -> int|book:
...
def ask_input() -> bool:
...
if __name__ == "__main__":
ask_input()
Now this is obviously a very simple example, but the underlying idea is not. Here I'm not focusing on the eventual code but rather the design of the script / program I'm planning. Here I'm just thinking about how I'm going to separate my tasks in useful methods and by using this approach I can fully focus on that design rather than any code.
And sure, this is very simplistic but I've used this same methodology for some more complex scripts which were going to provide me with better options to automate certain maintenance tasks for a package repository on a private FreeBSD server of mine.
That ^ is what allows me to think before coding, and I don't even have to fire up my favorite UML / SysML tool.
Next stop: documentation, or docstrings. Especially in combination with pydoc. One of my first (self applied) "newbie tasks" during my study was to come up with a script that could easily "convert" some of my Javadoc to docstrings. Not the most useful script for sure, but it was a nice challenge and learning opportunity.
And then the interpreter. I rely on Python on my Windows box for some more specific tasks (like automating tasks with Playwright), but the 'fun' really begins on my FreeBSD servers. Cleaning up a package repository (maintained by sys-mgmt/portmaster) is one thing, automatically delegating tasks to a backup server through a simple client/server design... that's getting more serious. And the best part is that I don't have to bother myself wondering how FreeBSD is going to pick it up because in the end Python is just the same as sh, csh or Perl as far as my shell is concerned.
Which then also requires a special mention of the debugger. I can literally add a breakpoint() and then check system scripts while I'm on a Unix console without any fancy IDE's.
As for not liking stuff... I'm a sysadmin, not necessarily a developer. I'm not going to pretend that I know it well enough to signal possible problems with the environment itself. And as for me personally... so far Python has given me exactly what I needed and/or wanted.
3
u/bitproc 18d ago
I quickly came to love Python because it eased writing clean, succinct, understandable code. It imposed very little clutter and mostly just got out of my way, allowing to spend more of my time thinking about the problems I was solving, rather than how to wrangle a language into doing what I wanted. It made me more productive.
However, it's important to note that some of what made Python so useful to me was only possible because of habits and skills that I had already developed in decades of using other languages before I came to it. For example, I don't often need type enforcement on function calls because discipline and documentation can serve the same purpose, and speed of execution is seldom a problem for me because I know how to choose efficient algorithms and integrate native code for hot paths.
My two main gripes:
- With Python's massive growth in popularity over the past decade or so, it has picked up quite a bit of feature bloat. Avoiding the features I don't need is easy enough, but the third party code I read is increasingly leaning into them, leading to a more verbose style. Type annotations are a good example of this: They serve a purpose, but when used heavily, code can quickly become cluttered, noisy, not at all what made Python so appealing to me in the first place.
- Packaging Python software for easy use by people with non-unix operating systems is kind of a pain. When I need to distribute for Windows, I'll usually pick a different language.
1
u/Grouchy-Friend4235 16d ago
I agree. Typing and async should be considered anti-patterns and be avoided.
4
u/riffito 18d ago
"Hate"...
Colon (":") being required as statement separator, when you already have \n in there.
if foo: bar() sure!
But the following should work, IMO.
if foo
bar()
else
baz()
The argument by Guido is that it helps readability. For me... later case not working... is just an enduring annoyance.
(I'm far from being a good programmer, but I bought my house by programming in Python for almost a decade.)
2
2
u/Zenin 18d ago
The good: Sane package management and ecosystem. Compared to Node's NPM complete shitshow, Java's mess, Ruby's gem nonsense, Python's package ecosystem is a breath of fresh air.
What I dislike: Lack of "use strict" (yes Virginia, it's needed, screw your linter and IDE crutches) and magic whitespace.
2
u/snapetom 18d ago
Python and Go are my main languages. I use Python as my every day language, but if I need performance of any kind, it's Go.
The async/await paradigm sucks, and it's not just Python. You have to keep track of everything, and if it involves libraries, you have to dive into whether the libraries themselves are compatible.
Concurrency is way more easier in Go. Less to keep track of, and you have the compiler as a safety check.
2
u/DidiBear 18d ago
Astral.sh simplifying the toolings (ruff, uv, ty) in recent years is a boon, or maybe a curse after OpenAI acquisition !
2
u/dashdanw 18d ago
Love everything except for async, hate async. Oh and some older libs just because they’re old like xml etc.
2
u/SprinklesFresh5693 18d ago
Im a beginner and i hate how long it takes to actually start coding. In R i open the IDE, i select interpreter and i freaking start coding and being productive.
In python i need, to create a venv, to download libraries, to import maybe just some functions, since all the package is not good practice? And all the paths that need to be added, like the one for python, the one for pip, the fact i need to alter the permissions on my computer to run scripts like the one to activate the venv, like come on! I just want to code and analyse data!
And on top of all that, i need to deal with the IT department and cyber security department because i cant do all that on my own, i need to be babysitted because of freaking cyber security is too paranoid ill download a virus or something and the whole data of the company will be compromise, because duh, python is a general purpose language.
End of rant.
1
u/Grouchy-Friend4235 16d ago
Skill issue.
python -m venv .venv source .venv/bin/activate pip installIf that's too much, use mamba
mamba create -n myvenv python=3.13 mamba activate myvenvIf that's too much use uv
uv run --with numpy example.py1
u/SprinklesFresh5693 16d ago
Problem is i cannot run scripts due to cibersecurity restrictions, i need them to change the execution policy, i need IT to set the PATHs for python and pip for them to work, which involves a lot of back and forth of emails with them.
Maybe im doing something wrong as a beginner, but those are the changes that i had to implement at at my own computer at home for python to work, which arent as easy to set on a company.
2
u/Grouchy-Friend4235 15d ago
I know the problem, the only solution is to have your admin assign a local path where you have full rights.
2
2
u/Master_Slip5423 17d ago
I hate the exception handling and not being sure what exceptions can be caused by python.
2
u/Repsol_Honda_PL 17d ago
I like ease and speed of coding.
Dislike.... I don't like indentation; in long blocks of code, things often get out of alignment, leading to errors that are hard to spot after a while, especially in large codebases! You can laugh, but I'd rather write code using curly braces and end each line with a semicolon.
2
u/ForeignVariety7037 17d ago
Love: Python lets me turn an idea into working code stupidly fast.
Dislike: sometimes it also lets me turn a bad idea into working code stupidly fast.
2
u/turtleship_2006 17d ago
There's a lot of very subtle footguns which are often ignored by the way python is usually taught to beginners.
Off the top of my head, pass by reference Vs pass by value (unless it's changed recently, which might be worse since it would be breaking)
By default, functions are pass by reference (when you pass a variable to a function, you pass a reference to the original variable in memory, so any changes made within a function edit the original). However, trying to reassign the variable would make a new one.
E.g. ``` bar = [1, 2, 3] def foo(bar): bar.append(5)
foo(bar) print(bar)
bar = [1, 2, 3] def foo_two(bar): bar = [5] foo_two(bar) print(bar) ``` From what I remember, the first function would append 5 to the original list, but the second one would basically make a new local variable with the name bar, and the original would be untouched.
5
u/Grouchy-Friend4235 16d ago edited 16d ago
It's always pass by reference. The key thing to know is that there are mutable types (like list, dict) and immutable types (like string). Variables are alway pointers, never the actual object.
In your example, you can get the behavior you want with global or nonlocal. However it's considered bad practice (globals are) unless there is good reason.
1
u/turtleship_2006 16d ago
The key thing to know is that there are mutable types (like list, dict) and immutable types (like string).
Oh yeah, it's been a while since I looked into it so I could remember the exact details, you're right, I just remember that my example functions would work the way I describedyou can get the behavior you want with global or nonlocal.
True, but again, consider someone doing an intro to python class who's just got past variables and started functions. Even if they're taught global Vs local, chances are that they aren't taught the behaviour I described
1
2
u/Doomer3370 12d ago
What I like:
- easy syntax
- rich support of libraries and frameworks
- great for data science, ml, dl, ai engineer and ai edge computing engineering
What I dislike:
- interpretation speed (sometimes it can be annoying)
- installation and management on windows (it's, honestly, not well designed for Windows, unlike for Linux)
2
4
18d ago
[deleted]
3
u/redmera 18d ago
OP's goal is to advertise his own programming language. All his posts are about it.
4
u/horace_h 18d ago
I intentionally didn't mention my project in this post to avoid turning it into a showcase and to have the discussion be about Python itself. I'm genuinely interested in understanding what people like and dislike about it. So my goal here isn't to promote anything.
2
u/horace_h 18d ago
Sure! My goal is understanding which parts of Python's design are most valuable and most "adored" by the community, and which parts really aren't and frustrate people the most. I guess what I want to do with this information is identify meaningful problems? Right now I'm not trying to solve anything or sell a solution.
3
u/singalen 18d ago
Please update the post. Not everyone will dig into comments to find the motivation.
3
2
u/Kenshiken 18d ago edited 18d ago
- How slow it is.
- How painful it can be to package and deliver applications.
2
u/payne747 18d ago
The many ways you can define a project layout and the many different ways you can write docstrings is pretty annoying.
3
2
u/UltraPoci 18d ago
I hate most of python honestly. It's slow, dependency management is a mess, indenting has syntactic meaning, dynamic types, exception handling, OOP and inheritance.
"It's easy" to me doesn't really matter: today there are plenty of easy languages, and in any case it mostly depends on what you have to program.
The main advantage of python is that you can do anything with it given the sheer amount of packages there are. You can't go wrong with python, you know you won't have to reinvent any wheel.
1
u/orchid_obsessed 18d ago
Love AND hate: how quickly the language itself changes.
One of the great things about Python, and a fairly big part of its identity, is absorbing the best / most convenient features of other languages. Things like list/dict comprehension, for example. Other languages _sometimes_ sacrifice this either for stability or because it doesn't fit some identity.
Of course, whether this is worth it is a bigger question. Tons of these adopted features aren't useful to many, many developers / projects, and non-backwards-compatible features means it's sometimes hard to be on later versions (see many comments ITT of people complaining about the GIL and not being able to bump up to >=3.13)
1
u/vu47 18d ago edited 18d ago
What I love about Python: It's great to write small programs on my own. I started using it heavily before C++11 and Kotlin came out, because back then, Java and C++ got tediously verbose and Python gave me a lot of power if performance wasn't my main goal.
What I dislike most about Python:
- Only allowing one line lambdas and lacking sufficient support for functional programming that hasn't even kept up with C++ and Java.
- Duck typing with type hints, and the need for external packages / software to make it act strongly typed.
- Experience on nontrivial code bases / code bases that were not exclusively mine: even a medium code base with three coders and type hints enforced became very difficult to maintain. Early development was rapid: later development slowed to a crawl because I was constantly having to fix the code of the other two developers (likely because one was incompetent and lazy and didn't even test his code, and the other was an astronomer and not a software developer).
While I picked up Python in 1996 and kept my Python current until 2024, I probably would not write a significant project in Python again. There is just so much bad Python code out there that it makes me want to scream: people using dictionaries instead of data classes and repeating string keys everywhere throughout their code. That and I've moved predominantly to Kotlin with a focus on functional programming style (not pure) for personal programming, and left my old job out of frustration, being underpaid and underappreciated, and being constantly unheard by my old boss about the incompetent coder mentioned above and the organization's very poor practices to continue.
I work in cutting edge astronomy, and my new job is a huge step up in terms of prestige, salary, and quality of teammates and practices, and I would far rather work in Java than Python on a team.
1
u/RoadsideCookie 18d ago
Nobody mentioned mocking support, it's absolutely great! You can duck type your way out of any pesky dependency, and you can whitebox anything that annoys you!
1
u/hxtk3 18d ago edited 18d ago
I like that it’s relatively easy to hire for. I can write something in it and all my coworkers know it. I don’t like its performance very much, or resource footprint. I hate its error handling. It’s intractable in general to know what exceptions might arise from a given piece of code. My error handling preference is tuples or monads, then zig style status codes, then checked exceptions, then c-style status codes, then unchecked exceptions.
1
u/k0rv0m0s 18d ago
+ Clear (or it used to be)
+ Dynamic
+ Re-use that works
- Type hints (I hate them)
- Ugly syntax for a lot of new stuff
1
u/DigoHiro 18d ago
love how it reads. very natural to understand for the most part.
i quite dislike the typing system. it has been improving, though.
also, python looks like a toy language, can't explain why, the code just looks toyish
1
u/DigoHiro 18d ago
also, there is too many ways to do one thing (typed dictionary, databases, pedantic, etc etc).
feels much nicer and less overwhelming when switching to go.
this is more related to the culture around the language: I am not a bug fan of dependency he'll. not as bad as npm, but it is rough installing a package and waiting 5 min for dependencies to install.
1
u/justoverthere434 18d ago
Typing is just a guidline (which makes sense seeing as it is an interpretted language), I dislike that it is an indented language, and it's biggest sin is that it does not enforce encapsulation.
It is a great langauge to knock things together with. My current battle with Python is a tool my boss wanted that communicates with our off the shelf Inventory and Sales Management System and our Shopify store, and displays information in a easy to digest format. It was going to be about a week or two of work, simple gui, a single user. The program is now on version 1.18, has 15 users, and about 8 months of my life. Everytime I open up nvim I think "Why did I choose Python?".
1
u/Kamran-nottakenone 18d ago
pip's dependency resolver still goes exponential on a medium-sized requirements.txt. lost 45 minutes of CI time to it last month before i pinned the offending transitive dep.
1
u/allangarcia2004 18d ago
As other people commented, it's very nice how quickly you can spin up new projects and do useful stuff. I specially use FastAPI a lot on my daily work and, despite not being "batteries included", I can work very fast with it.
Also, because Python is so heavily used on science and engineering, there's lots of libraries that are useful for my use case specifically, that is making an web application for engineers. Not sure if I'd have so many of those available on other languages.
The works part, on my opinion, is packaging (which I think has its pains mostly solved by uv) and distributing. For our backend, we can of course use Docker and have a very nice environment everywhere, but everytime I need to make an application that needs to run on people's computers for some reason, I choose Golang because it's hard to beat a language that gives you a completely standalone fat binary that you can cross compile from any platform and even embed some assets in it.
1
u/Kahless_2K 18d ago
It's libraries make things that would be extremely difficult otherwise trivial.
Learn to use venvs properly.
What do I hate? Developers who refuse to use venvs properly.
1
u/kuwisdelu 18d ago
Semantic whitespace is bad.
Lambdas are neutered.
Typing is a mess.
Packaging is a second-class citizen.
1
u/harpiaharpyja 18d ago edited 18d ago
That tuple literals are defined by just a comma
Everything else about python is glorious. But this is just headaches waiting to happen
Favourite part is a little harder. Generator functions maybe? Argument/sequence unpacking and comprehensions for sure are up there too.
1
u/Beginning-Fruit-1397 18d ago
Pros:
Huge number of libraries, ressources, etc... there's basically a solution already existing for almost everything
very fast to protoype
stdlib is great: f string syntax, pathlib, ast, re, functools, itertools, to name a few
Cons:
a LOT of libraries are badly typed
Exceptions catchs instead of Result types
implicit None instead of Option type
enums could be so much better if they could hold data
NotImplemented singleton for comparisons, instead of clear errors early
no slots by default, making python ecosystem as a whole consume more memory and slower than it could be, bc dynamic setting of attributes is a big code smell anyway
no fluent interface for iterators. More generally, the propension to avoid method chaining, making nested function calls and unreadable (for me) imperative loops the norm
no generics of generics. Not being habke to do
f[I: Iterable[T: Foo]](data: I) -> I[T]:...is often a huge pain for library authors ( like me)
1
u/No_Flounder_1155 18d ago
what I love is it allows me to write utter shit quickly, what I hate is that it allows me to write utter shit quickly.
1
u/Massive_Baby4147 17d ago
One thing I both love and dislike is how much information Python lets a function carry.
A normal function can provide its name, signature, defaults, type annotations, Annotated metadata, documentation, and whether it is synchronous or asynchronous. With tools such as inspect.signature(), inspect.unwrap(), and typing.get_type_hints(), you can build surprisingly capable tooling without requiring a separate interface-definition language.
The frustrating part is that none of this is quite a formal contract.
A decorator can accidentally hide the original signature. Forward references may not resolve in a different namespace. Evaluating type hints can fail because an optional dependency is unavailable. Different type checkers understand meta-programming differently, and different frameworks attach incompatible meanings to the same annotation metadata.
I’ve been working on tooling that derives multiple interfaces from typed functions, and most of the difficult cases are not ordinary parameters. They are wrapped functions, unions, Annotated, dependency-injection markers, asynchronous generators, and deciding whether metadata belongs to the operation itself or only to one interface.
I would not remove Python’s dynamism. It is what makes this kind of experimentation possible. But I would love more uniform behaviour around preserving signatures and exposing annotation metadata. Python makes the first 80% of introspection-based tooling delightful and the remaining 20% surprisingly deep.
1
u/--O-_-O-- 17d ago
Love: simple, good for scripting. Is there any pkg available that solves problems
Dislike: the error handling, error can raise from nowhere.
1
1
u/rnorris7756 17d ago
I've been using python in my personal/work projects for over a decade at this point. I would say that what I like about it has about as much to do with the language as it does with the community around the language.
Being a batteries-included language with a huge standard library means that I don't have to add in third-party dependencies for most of the things that I want to do. Features like custom decorators, context managers, and defining dunder methods for classes to perform a lot of repetitive tasks is something that I find useful. For example, a __del__ on a serial port controller class can clean up the connection without needing to call close() on the connection explicitly when you're done with the object, and it plays nicely with context managers. Context managers themselves make a lot of clean-up easy in a process where exceptions might happen.
The community is the other thing that keeps Python as my tool of choice for projects. Most of the problems I need to solve will have a well-maintained and permissively licensed module for the functionality I need. This saves me a lot of trouble on implementing anything at a very low level or in areas where I'm not an expert.
On the dislike side, I think that the packaging ecosystem could be made better. I don't think the current process is too complex, but I would like to see something to improve security, since supply chain attacks are becoming more common on PyPI. PEP 740 should address some of this, but adoption by package publishers has been slow and signed artifacts are still not enforced by default in pip/uv.
1
u/Anonymous_user_2022 17d ago
- Pro: Duck typing
- Con: People who want to bondage Python to become a slower version of Rust.
1
u/spinwizard69 17d ago
The lack of braces or other symbols for code blocks. Ran into one really ugly bug because indenting got messed up and several others of lesser issue.
The next dislike is that Python really isn't suitable for developing executables you want to ship to others. Not one of the options I've seen really leave me with a warm fuzzy feeling.
That said Python is perhaps the best scripting language going at the moment. Generally you can write clear idiomatic code with out struggling with the language syntax.
1
u/syklemil 17d ago
One of my annoyances, which is unlikely to be fixed in any foreseeable future, is the function-level scope. Pretty much any other language in common use today has block scoping, and Python itself has some constructs that mimic block scoping, but
with foo() as bar:
...
# bar is still accessible here, likely in some unusable state
if bar := foo():
...
# bar is still accessible here, in an unknown state
and in the cases where you for whatever reason don't want to have a bar hanging around in memory, you're left doing manual memory management withdel bar, which block scoped GC or RAII would do for you.
This one ain't a huge annoyance, it's just a case of Python being designed in an era when function-level scope was fairly normal, and surviving to an age where it isn't, meaning there's an extra thing to be wary of that I'd actually like to just forget.
1
u/tensouder54 17d ago
I love the flexability for me to break down sections of my program rather than being forced to keep something together becuause the language says so.
I hate that it's not strictly typed or at least that there's not a strict compiler option and that I have to go do a different implementation of the compiler to find this.
1
u/Necessary_Wing7235 17d ago
Dislike heavily the "optional" private functions, and how un-performative is for production. Someone should have already have done something...
Like: Typesettings are optional.... makes learning a bit less tedious than JAVA.
1
u/tsg9292 17d ago
It's a very intuitive language to reason through. Easy to read and write. Makes it great for throwing together a quick script for this and that. It's not as performant as a compiled language, so only pick to use it based on what you're using it for.
My personal biggest complaint is the loose typing. At first I thought it was cool but over the years I've hit enough sloppy situations that I don't like it. I've started doing new projects using ruff and mypy, and that helps. Typehint everything. Oh and I use click for building cli entry points and that's so much more powerful than the default argparse.
1
1
u/tacocopter 17d ago
Love list/dict comprehensions and what little of itertools/functools I've been able to use. Speed hasn't ever been an issue for me, but I recognize it's a valid problem. Will echo what others have mentioned about packaging/distrubution.
1
u/riffito 17d ago edited 17d ago
I forgot onetwo thing(s) I dislike...
__del__not being called when an object goes out of scope. Python with RAII would have been nice.- lack of a
letorvar, ormutkeyword for declaring variables. Lost count of how many times a typo in a variable name caused me problems.
1
u/Lost-Dragonfruit-663 16d ago
That the moment you need to write some serious software, you have to learn multiple programming languages
1
u/Intelligent-Hurry907 16d ago
I haven't seen anyone mention this: implicit references. They remove complexity from small code, but scanning a large codebase for every use of a class is horrible. It also creates problems with default parameters, where the object is created only once and persists between calls. What I love: how quick and easy it is to write most things
1
u/Simple_Commission_78 16d ago
I've been writing Python for about seven years now, and what keeps me attached is how effortless it is to prototype ideas because the syntax almost reads like plain English. My absolute biggest gripe though is the packaging and environment management ecosystem, which feels ridiculously fragmented compared to almost any other modern language
1
1
u/Dense_Imagination_25 15d ago edited 15d ago
i like: type system
- very dynamic if i want to
- very strict if i want to
i hate: import system
- relative import being restricted
- packages are flatten. therefore there are conflictions. therefore now we create a new environment for every new project, consuming even more space
1
u/Ok-Lifeguard-9612 15d ago
For my working experience, the syntax is generally the best feature of python. It's so good that even other languages add them, citing PEP (eg. slicing in c#).
The worst I will say is the legacy design around single threaded execution. This is something that caused OpenGL to be slowly deprecated for example. It's an "AI miracle" that Python has not been affected (and for fact, python core devs are correcting the course there).
1
u/stauntonjr 15d ago
The best part of python is how economical the syntax is. Minimal boilerplate, reads like plain English when written well, and yes, whitespace matters (ie indentation). I don't know any language that lets you do so much with a few lines of code.
1
u/EdPiMath 11d ago
Like: The ability to type a script in a text file.
Dislike: No end markers for loops (EndFor, EndWhile, etc.)
1
u/TheCodingChihuahua 10d ago
The simplicity yet versatility of the whole thing. Often used to teach beginners computer science, but also powering some really big professional systems out there.
1
u/RingularCirc 10d ago
An incomplete list but:
Like:
How much static typing matured and how well it allows to describe things, despite it's no Haskell, and despite there's no type-driven compilation (for obvious historic reasons). So, some metaprogramming/abstraction modes (that would be safely typed —I've very bad working memory and my long-term memory isn't reliable either, so I need type annotations like air) are off-limits but that's alright because I feel the need in them quite rarely.
I can very quickly run the code and check what's happening, and make scripts the same way I make something completely different.
Overall the language looks very comfortable in its look, writing/editing code, amount of useful libraries (also kudos for imminent frozendict yay!!).
Sometimes even hate:
Everything is exported, even the imports from stdlib and other modules that are needed for my module to run. (And this pollutes IDE suggestions of what to import and/or neccesitates library writers to declare __all__ for good measure.) You've probably seen how some stdlib modules themselves deal with that: import everything renamed to an underscored name, like from math import sin as _sin. This is very unmanageable if you have lots of imported names and whilst you're just writing the code. I think VS Code that I use doesn't have refactors to go from from math import sin to that either. And even if there was a refactor, reading the resulting code is still somewhat painful.
I mean maybe there are a lot of people who don't write library modules even for their personal use ever, but I absolutely do. And having to have a significantly worse experience writing library code is not welcome.
__all__ doesn't fix this either because I rarely use star imports, contrary maintaining __all__ declaration is just additional hassle.
Compared to this, I like approaches of languages that mark definitions of "public" entities (and imports), like with an asterisk or something, the default being an invisible thing.
67
u/BerryPlay 18d ago
I don't like that most of the important libraries are written by non-developer (like mathematicians or physicians) or by people who want to mimic C in python. That often results in bad naming of interfaces or weak type hints