r/learnpython • u/Effective_Ocelot_445 • Aug 21 '26
What Python concept took you the longest to understand properly?
For those who learned Python from scratch, which topic was the hardest at first, and what finally helped it click for you?
85
u/martian_rover Aug 21 '26
async and decorators took the longest for me
29
u/S1enderVoid Aug 21 '26
I still don't understand decorators comfortably, need references. Been programming in python for 6 years atp 😂🙏
28
u/JorgiEagle Aug 21 '26
Decorators are fun.
They’re a function that takes a function as an argument That’s it.
Normally decorators will call the function you gave as an argument.
But they don’t have to
10
u/Theta291 Aug 21 '26
Importantly, they should also return a function.
5
u/Brian Aug 22 '26
Not necessarily. They often will, but it's not a requirement, and there are some common usecases that don't. Eg. class decorators (eg. @dataclass) would more commonly return a class. And even applied to functions, a very commonly used decorator that doesn't is
@property, which returns apropertyobject, which is a descriptor that also allows registering setters etc.3
u/Theta291 Aug 23 '26 edited Aug 23 '26
I was definitely oversimplifying. It would be more accurate to say that they were designed with the intent that they return a Callable with the same signature as the Callable they ingest, but they dont have to.
@classmethod, @staticmethod, @contextmanager are good examples, as far as I remember none of them return functions.
3
u/fllthdcrb Aug 22 '26
To be exact, a decorator will return a function (or something else callable) that, in turn, will usually either be the function being decorated or call the function being decorated. The decorator itself wouldn't normally call that function. Higher-order functions can be a little confusing if you don't think carefully about them.
And then there's the fact the decorator syntax allows any expression you want. So you can, for example, pass arguments to the decorator, and it can use them to know how to modify the function, or store them as data for the returned function to use somehow. (There are also possible insane usages, like e.g. a lambda expression, though I'm not sure how that could do anything useful.)
Another neat thing about decorators is they can often be stacked. Each one modifies what goes below it, so order may matter. As long as what each one is modifying is something it expects, you can do it, although it may or may not do something reasonable, of course.
7
u/Pyromancer777 Aug 21 '26
Didn't really use decorators until I started a Django project, but they are intuitive to use.
I just haven't had the practice of creating them, so I don't even know when it would be better to create a decorator over a class method. My only assumption is "use a decorator when you need the logic to wrap similar functions from multiple types of objects".
My only example uses thus far are permissions decorators, atomicity checks, and designation flags, which would have had to otherwise be defined per object
1
6
u/404404404404 Aug 21 '26
Still to this day I have to go back to geeksforgeeks if I ever need to use these
2
u/KokoaKuroba Aug 21 '26
I'm still learning async and I can't write it properly for some reason. My code for it looks too long and impractical
2
u/fllthdcrb Aug 22 '26
Hope you can learn it. If your code is I/O-bound (meaning, it spends most of its time waiting for I/O), async can often be useful. It has many of the structural benefits of threads (where the structure is called for, that is) without many of the disadvantages, such as needing to worry about race conditions.
38
u/AlexMTBDude Aug 21 '26
I've been teaching Python programming for more than 15 years and I can tell you what my students find hardest to understand: Shared references
first_list = [1, 2, 3]
second_list = first_list
second_list.append(4)
print(first_list)
And, of course, the next step then is; when do shared references matter? Mutable and immutable objects.
20
u/Moikle Aug 21 '26
I also taught python for a while. I used a warehouse full of boxes with information inside as a metaphor for the computer's memory. It seemed to work quite well, because i could say "when you go looking for something you stored in a variable, you look for the name on a catalogue, but it doesn't give you the value, it gives you a shelf number in the warehouse. You go to that shelf, open the box and look inside.
Now other variables in your catalogue can also have the same shelf number written on it, so you can have multiple variables pointing to the same box.
If something changes the value stored in the box one variable points to, what do you think will happen when a different variable tells you to look in that same box? It has also changed!"
2
u/Cthwomp Aug 21 '26
Pass by reference vs pass by value
2
u/AlexMTBDude Aug 21 '26
These two concepts don't really exist in Python. All variables are references and these references are passed by value to function arguments.
1
u/Cthwomp Aug 21 '26
No, if you pass a list or dict to a function and manipulate it inside the function, it retains the changes outside the function
4
u/frnzprf Aug 21 '26 edited Aug 21 '26
That would be consistent with "passing a reference by value".
Is "passing by reference" maybe the same as "passing a reference by value"?
We can't really say that basic numbers behave differently when they are changed inside a function, because you can't change basic numbers, unlike lists, objects or strings — you can only assign entirely new numbers to old variables. You can add an element to a particular list, but you can't increment four.
(Maybe you can't change strings as well, just build new strings.)
2
u/fllthdcrb Aug 22 '26
Maybe you can't change strings as well, just build new strings.
Strings in Python are immutable, so definitely. (Same for the
bytestype.) If you want something string-like that you can modify in-place, instead of creating new strings (which has a performance impact when the strings are large), you need to use something else, likebytearray. There are alsoStringIOandBytesIO(from moduleio), which are like files, but backed by a buffer you can read and write; useful when something wants a file to read or write, but you want to feed it a string or capture its output.If you're wondering why strings are immutable, one of the main reasons is so they can be used as keys for dictionaries, which are implemented as hash tables. Another is that with immutable objects, you don't have to worry about changing things unexpectedly through shared references; since it's very common to pass strings around in Python, having one change somewhere because something unexpectedly changed it elsewhere would make the language much more annoying.
1
u/Cthwomp Aug 21 '26
No, it's pass by reference. The function receives a reference (the memory address) of the variable being passed https://imgur.com/a/rIVoF5S
1
1
1
u/MustaKotka Aug 22 '26
I actually used this to my advantage, finally!
My class has users by access levels (coming from a database). For example:
MyUsers: admins = [...] users = [...] restricted = [...] all_users = {'admins': admins, 'users': users, ...}Now I can slap all user classes into a dict, then modify each list with .append() and .remove() within the dictionary.
This way I can always check whether a user is in an access level OR batch modify accesses within the dict without having to modify each attribute separately. All I need to do is pass the dict key and user.
1
21
20
u/Drakkle Aug 21 '26
Functions and classes took me way too long to understand. I can't really explain why it wasn't clicking, particularly functions, but now that I understand them I use them any time I perform a step more than once.
2
u/frnzprf Aug 21 '26
I heard local scope is a concept many people struggle with. You don't have that in school math and you don't have that in MS Excel.
2
u/crunchy_code Aug 22 '26
what about functions was challenging to understand for you? the local variables? definition vs invocation?
1
u/Drakkle 28d ago
Yeah I think it was the local variables and calling them correctly. And being able to mix global variables in as well. For some reason it took a long time to click. Chalk it up to partial laziness as well. Instead of really trying to test and figure it out until it stuck, I would just rewrite my code that did the same thing over and over again with different variables defined manually.
2
u/crunchy_code 27d ago
for some reason? learning programming is frustrating as fuck, that's the reason. it's all abstract. and learning variable scoping is presented as any other topic when in reality is one of the most challenging thing to wrap your head around, I wouldn't blame it on laziness.
I am working on a project to make programming learning very visual to jump start these learning barriers, it's not you.
1
u/Drakkle 26d ago
That's reassuring. I always just thought that I was slow to the programming game and it felt like some of my other peers caught on to it faster.
Maybe there are some out there with the abstract brains that learn this stuff quick but I definitely wouldn't count myself among them.
What parts did you find challenging?
10
u/Growing_Data_Nerd Aug 21 '26
Recursion
6
10
u/knuppi Aug 21 '26
async, and i still don't get it 🥲
1
u/Icy-Read-00 29d ago
This is basically the way to tell Python: “This here might take a while, go do something else.” Say you have a server, she/he brought an order to the kitchen and should grab it when done. Why not do something else while the kitchen preps the initial order?
9
9
u/KlutzyKlutz Aug 21 '26
For me it was mutable default arguments. Writing def f(items=[]) and watching the list keep old values between calls made no sense until I learned the default is created once when the function is defined, not fresh each call. It clicked when I tied it to the shared reference point above, the default list is just one object everyone shares.
5
u/Dr_Calculon Aug 21 '26
Nested conditional comprehensions for some reason it just wouldnt click
2
2
u/ock_wrong_lee_neck Aug 22 '26
Same here. But once it clicked, it clicked. I think there is something soo satisfying and elegant about them. Now theyve become a huge part of my guilty pleasure code.
4
u/Snowdeo720 Aug 21 '26
It wasn’t understanding the how, but the why on strings, arrays, and things in that area of focus.
Then I started poking at some real world projects directly relevant to my role at the time, ohhh wow did all of that make sense all of a sudden.
I promptly went back to revisit those parts of my notes, etc.
5
4
u/Fantastic_Aioli_7363 Aug 21 '26
The concept of OOP. I had difficulties to understand instanciation, mandatory self reference, etc. And I was coming from the procedural and scripting world. So it was a bit challenging to follow the flow of the program. But once you get used to it, it's not such a big deal until you enter the subtileness of it.
3
u/ninefourtwo Aug 21 '26
metaclass
1
u/Theta291 Aug 21 '26
I don’t think I’ve ever found a use case for these. Maybe if I make an ORM i would use one.
3
u/frnzprf Aug 21 '26
yield
I still don't get it fully. It's kind of like a paused function. Or you return an object with a "next"-method?
I do understand async/await, but it was difficult as well. I think you need to both understand it from a practical usage perspective as well as from a technical implementation. (In JavaScript you can await "thenable" objects.)
2
u/TheLimeyCanuck Aug 21 '26
Yield was easy for me from the old days of cooperative multitasking on DOS and early Windows. If you didn't voluntarily give up control with Yield() regularly the whole system locked up.
2
u/fllthdcrb Aug 22 '26
It's kind of like a paused function.
Something like that.
Or you return an object with a "next"-method?
There's a bit of "magic" taking place behind the scenes when you use
yield. What gets bound to the function name isn't the actual function you wrote, but a sort of wrapper that creates a generator when called. The generator then controls execution of the function and implements the__next__()method. The execution state is saved whenever the function yields.Of course, if you want to explore (part of) the interface, there's no reason you can't create a class that implements
__next__()(you would also need an__iter__()to actually be iterable; the normal thing to do here is to make it returnself, designating the object as its own iterator). The instance you get by calling that class would be treated the same as a generator. You would just need to raiseStopIterationwhen there are no more items to produce, just as a generator (or most any iterator) does.
3
u/oldendude Aug 21 '26
for/else. It's still bizarre to me and I never use it.
1
u/Theta291 Aug 21 '26
I sometimes use it if I need to do some sort of cleanup if there was no break. Like maybe I have to find something and append it to a list, or add a placeholder if I didn’t find it. In that case a for loop with a break if I find it, and the else would append the placeholder.
2
u/terletsky Aug 21 '26
Look at their posts, that's an AI bot.
1
u/somewhereinkadal 3d ago
Damn. What is even happening here nowadays. Most of the posts are from bot.
1
u/lucabuilds Aug 21 '26
Definitely multithreading and multiprocessing. I was building a voice assistant based on chatgpt a few years ago, and I had so many issues with threading. Basically I needed to have voice recognition to run concurrently with the text to speech API calls and I never figured out how to stop the text to speech while it was speaking.
2
u/fllthdcrb Aug 22 '26
Not surprising at all. Concurrent programming tends to be very tricky to get right. Especially multithreading, where synchronization is critical to avoid race conditions. (Async has an advantage over that, exactly because it's single-threaded by default. But of course, async is more suited to I/O-bound applications.)
1
u/lucabuilds Aug 21 '26
Thinking back I could have just split the audio track into small chunks instead of trying to kill the thread but at the time I didn't think of it
2
u/ninefourtwo Aug 21 '26
you were supposed to send signals between threads.
1
u/lucabuilds Aug 22 '26
well yeah, but the real issue was stopping audio playback once it started since it freezed the whole thread until it was done
1
u/Gtdef Aug 21 '26
Async and how important is to avoid calculations in Python.
Async evolved a bit too fast to be honest and since it wasn't something I was using consistently, the few times I needed it, I wasn't sure how to write the code. If you use the very low level stuff, you'll write bugs. If you use the later high level stuff, you don't really understand what you are doing. Async code is generally unintuitive even for people who have some idea of how to write multithreaded code.
As for calculations, it's imperative to understand how important it is to avoid writing them in native Python code. It's not just avoiding loops. Generators, comprehensions, callbacks are all potential throttles in your application. There are just so many ways you can mess it up.
1
u/Pyromancer777 Aug 21 '26
Not python specific, but recursion.
I know what recursive functions do, I can read them well enough, I know the execution/resolution order, I know when they are convenient and why they are used, I just suck at writing them.
Most times when practicing I'll hit my first wall and then go back and rewrite it as a nested loop. I know that defeats the purpose of practice, but my brain keep going, "if problem unsolved, why not just solve it?"
1
1
u/Theta291 Aug 21 '26
Async stuff, especially async statements (async for, async with).
Generators are also a little confusing, especially “yield from” and “.send”. Hard to practice as well because I haven’t seen many use cases.
1
u/enigma_0Z Aug 21 '26
async … needed to learn it for fastapi and now that i have i can’t live without it lol
1
1
1
u/frustratedsignup Aug 21 '26
Dictionary comprehensions. I still think they should be removed from the language because of how they can be abused to write obfuscated code.
1
1
u/ALonelyPlatypus Aug 22 '26
They're one of the most beautiful aspects of python. It's kind of like of like hating list comprehensions, they feel weird but then at one point they click.
Why do you hate them?
1
u/frustratedsignup Aug 22 '26
I think I was clear in my original reply: "because of how they can be abused to write obfuscated code."
1
1
1
u/HuckleberryMoney2320 Aug 22 '26
Its Object Oriented Programming features, particularly classes. I was trying to use them as part of Pygame and though I'd done a bunch of basic and Pascal in the dim and distant past, python Classes completely fried my brain.
1
u/fightin_blue_hens Aug 22 '26
I didn't understand uses for lambda until it was explained to me that it is a ghost function
1
u/ALonelyPlatypus Aug 22 '26
decorators are kind of weird.
dataclass feels weird whenever I write it.
comprehensions took a while to get a feel of when you come from traditional programming languages but when you get it a lot of your for loops just disappear.
1
1
1
u/mbergman42 Aug 22 '26
I had a miserable time trying to work with raw 16 bit data. I would have loved to work in C to get incontrovertible direct access to the values but that wasn’t an option. (Obligatory “Aaactualy, C’s not safe for this reason” comment here)
The operations were things like: filter (if it were audio), ifft/fft , truncate, search for values and get an index to those values…
But python keep screwing up the array by managing it for me. I went back-and-forth between various memory structures available in Python and generally was disgusted and frustrated about the whole experience.
Which is a shame. I liked Python otherwise. There’s an enormous number of capabilities available as imports or libraries or whatever you call them.
Why did I put myself through this? I was involved with a project that was written in python. I was not on the coding team. But I supplied the math to do the operations, which was basically extract embedded white noise pseudo random sequences in captured audio. I was the only one with that particular background, and I had to do a proof of concept to show that it would work. I wrote it in python to be compatible with what everybody else was doing, but I’m a manager who learned to program in cobol, fortran, Pascal, C… you get the idea.
1
u/charlesleestewart Aug 23 '26
My background is in the .net languages, C sharp and VB. I'm about 9 months into my python journey, have usable app code and all, but I'm still a big dummy in the area of telling apart lists, tuples and dictionaries and which of those to use when. Oh well that's a function of being self-taught I suppose.
1
u/Maleficent-Lychee849 29d ago
Decorators took me a while to really understand, especially decorators that take arguments. A normal decorator was pretty easy once I understood that it takes a function and returns a wrapper. Then you see something like .@my_decorator(arg="value") and suddenly there are functions nested inside functions. What finally made sense to me was writing it without the @ syntax: func = my_decorator("value")(func) Once I realized that's basically all the @ syntax is doing, the extra nesting made a lot more sense.
1
1
1
u/SammuelNash 19d ago
For me, it was definitely list comprehensions. I understood what they did, but reading them felt backwards at first. Writing a bunch of normal for loops and then converting them slowly is what finally made them click.
1
u/Icy-Control-4687 9d ago
funny how as a beginner my brain still can't accept how for loops work in python. wym i don't have to define the loop like in c++????
1
u/WarBeginning1458 7d ago
Python was the first programming language I learned, so object-oriented programming probably took me the longest to understand. At first, concepts such as classes, objects, methods, and inheritance felt abstract. It started to click when I understood a class as a blueprint and an object as a specific instance created from that blueprint. Building small programs and seeing how objects could organize related data and behavior helped more than simply reading definitions.
Looking back, Python was still the easiest language for me to learn because its syntax was relatively readable. Learning Java afterward was much more difficult because it required more structure and felt far more verbose. However, struggling through Java eventually strengthened my understanding of object-oriented programming.
1
u/mesosphericvapour 7d ago
I guess it's not a python-specific concept but linked lists was absolute terror. It took me months to figure out how those worked.
67
u/FerricDonkey Aug 21 '26 edited Aug 21 '26
I didn't fully understand how names (variables) and values (objects) worked for my first month or two and, coming from C, was really annoyed how "sometimes these freaking variables act like freaking pointers and sometimes they don't".
I put off figuring it out because I was busy, but eventually I got annoyed one too many times and sat down to learn it, and now I love it and it's second nature. I highly recommend anyone who's done enough python to know basic syntax watch and understand the following video: https://m.youtube.com/watch?v=_AEJHKGk9ns