Python Decorators 1: The Basics
ฝัง
- เผยแพร่เมื่อ 5 ก.ย. 2024
- (For more, visit pythontutorial... !) In this video, I demonstrate the basics of function decorators in Python. I also demonstrate the @functools.wraps decorator for preserving docstrings of decorated functions.
You can download the Jupyter Notebook for this video from osf.io/szwhk/
This is the most underrated video/channel I've ever seen
Agree
You came like a saviour in my search options
The clearest explanation of decorators video that I found, and watched a lot of them! You have very good teaching skills!
I'm blown away by your videos! So much information and on top of that presented in a digestible way. Very unique. You got talent! Thanks! Keep up the great work! Greetings from Germany
I love the way you write list comprehensions from the inside to out. Really helps get them right and explain them well.
I love the pace. Followed without pausing
Best explanation i have seen so far!!!
When the explanation is hard to understand there is bitty chance the conveyor of the information does not have much knowledge about the topic himself. Which, is not the case here. Agreed.
probably the best tutorial on decorators on yt. deserves more views
Wow this guy exactly knows what the audience wants. 10/10. good job man!
What a great presentation!
I’ve been looking for a good explanation of what a decorator is, and this nailed it! A home run!
Thanks!
Agree with this.
Flat out the best video on decorators - a REAL, USEFUL example. Awesome.
Good Video, yes useful ? no
for word in names:
print(camelcase(word))
This guy;s teaching style is on another level. Thank you for the time and effort .
well said. I hope you do *many* move videos. You should consider teaching this stuff if you don't already.
The first three minutes of this explained what I've been struggling with from multiple books and other videos! bravo!
Hey, Very nicely explained! I finally understand what decorators are. One small thing though, what you are returning is actually PascalCase and not camelCase. Thanks!
Thanks for the example; it illustrated the concept of decorators perfectly!
I finally properly understood what a decorator is. Thank you!
You are such a great conveyer of information. Very concise and understandable. I appreciate these videos
Great work🎉!
Brilliant video, well explained.. was able to duplicate what you did and I am still a raw beginner only been trying to learn Python for about a week give or take. Thank you.
Glad to hear you find it useful!
Keep up the good work! New subscriber from Mexico!
Nice explanation, thanks a lot.
Just want to say 2 words... "Thank you".... was trying to understand this for a while and finally i got it!!
watched lots of tutorials that were explaining the python decorators!!! had to close videos one by one because they were explaining in such a complicated way! you really explained the same in such a simple way,... that even a non-programmer can understand as well :)) thank you very much
Decorators can be quite complex sometimes, but this intro is perfect. Great video as always, thanks. Looking forward to seeing more on this topic.
This is probably the first video that has made decorators make sense to me. Thank you!
Glad you found it useful!
Finally got the concept, thanks
Very well explained!
Thanks for the wonderful job of explaining the decorators in a precise and crystal clear way. Thanks a ton
Thanks very clear and I now understand alittle more today.
Very useful and practical
Excellent video
Thank you it was really a concise explaination. Subscribed
Great explanation, thank you.
That was a VERY good tutorial!
Concise and very well explained. Thanks for your efforts in creating these videos - really helpful.
Sebastian Mathot back with the hip-hop names :)
Thank YOU!
Thanks a ton! I watched your video on asyncio and immediately subscribed, and now this is the fifth video on your channel I'm binging.
I had a question though; adding the @mapper decorator to camelcase() works very well for when its passed lists, but breaks the original functionality camelcase() was intended for: which was to convert *strings* into CamelCase. With the @mapper decorator, writing camelcase("some_string") returns a list of each of "some_strings" letters capitalized into a list.
Isn't this incorrect?
Just wanted to say thanks for this and other excellent videos. Great job!!
Thanks!
This was amazing 🎉
I hate to be that guy, but this is actually Pascal case. Great tutorial by the way.
Awesome video! Just a small remark, ThisIsPascalCase, thisIsCamelCase (at least according to Microsoft) and this_is_snake_case. And this-is-kebab-case.
super one of the best explanation of decorator. Loved it! :)
Thank you. This was pretty clear explanation.
By the way - at 2:35 of this video - tried to follow along and typed the code as I see it .. and I was getting a lot of Name Errors ( It was complaining that "another_function" was not defined .. so the solution was to re-arrange the functions order as follows:
def turn_into_another_function(fn):
return another_function
def another_function():
print('another function')
def a_function():
print('a function')
a_function = turn_into_another_function(a_function)
a_function()
Now it works ...
That's correct. I made a mistake in the video, but the downloadable notebook is correct. (In the video there is no error because of the way that the namespace is preserved in a notebook.)
@ Thank you for your response Sebastian. I usually don't download stuff as I have plenty of "tools" already installed on my mac and so I type code as I see it on videos either straight on my interactive Python shell or using any of my code editors. Thank you for getting back to me. Nevertheless it was a good "challenge" to figure this out.
great tutorial,
This is the perfect explanation.
thanks man... made very simple to understand !
good video, clear explanations:)
Dude, you are gold. Appreciated!
Thank you for your effort in doing excellent and useful videos
I've learned a lot of things
Glad you learned something!
Perfection
This is really another Kickazz le$$on, watch, do and learn !!
If 2:30 NameError: name 'another_function' is not defined. Did you mean: 'turn_into_another_function'?
Solvation: move 'another_function' up to the most top
Thanks
hi sir, what I did not understand what you have done is when I tried to put the first input as a string it gave me an error again. Maybe we handled list input problem but we lost string input control. It seems we changed the entire function internal structure. Instead of defining a decorator, I could define a list splitter function like you did and put that function before splitting the underscored string. Am I wrong? I did not get the purpose of a decorator.
How to get a mindset to written python code in such a small lines?
For example, Below is the code snippet of camelcase function if it was written by me.
def camelcase(s):
# turn "this_is_a_string" into "ThisIsAString"
splited_list = s.split('_')
print(splited_list)
camelstring = ""
for word in splited_list:
capital_word = word.capitalize()
camelstring += "".join(capital_word)
print(camelstring)
valeu mano ajudou demais tmj
thanks a lot
I think i understand the premise of a decorator, but i don't understand why you wouldn't just for loop through the list like:
for name in names:
camelcase(name)
print(name)
I understand its a decorator explanation, but don't see the value in using a decorator?
Rappers in the camelcase, you rock !
Camel case actually has the first word with no capital. :)
b-e-a-utiful
you sir made my day thnx
Brilliant!! awesome!!!
I keep coming to this video when I forget how decorators work.
I find the @staticmethod pretty useful.
It is! I actually have a video on the topic: th-cam.com/video/upmOAPk2cK8/w-d-xo.html
Can someone explain why the original camelcase() isn't just hardcoded to behave differently in the first place? I get this is about dynamically altering functions, but I have a hard time seeing practical use in this, especially with the @syntax.
For example, after applying the @mapper decorator, the original functionality of camelcase() is completely lost, no?
Unless @mapper can somehow be "turned off", it can no longer handle a single string the way it used to...? This topic has me frustrated...
You never *need* decorators, because, as you say, you can also write a new function or directly modify the original function. However, a decorator is a convenient way to add functionality to many different functions. Caching is a good example of this. Say that you have thirty functions that all perform time-consuming operations. To speed things up, you could then build caching into each function separately. But a decorator allows you to do this more elegantly, by applying a caching decorator to all the functions. So that would be one use case. Such use cases, where decorators really help, are fairly rare, but you do run across them every once in a while!
Hi. Thank you very much for this explanation. Now I am very clear with Decorators. One last thing. What if I want to use the function for only one string?. For instance 'hello_world'. The output is not the one I expected.
I got this
['H', 'E', 'L', 'L', 'O', '', 'W', 'O', 'R', 'L', 'D']
and not this
HelloWorld
I assume the purpose of the Decorator is to use the function only for list of strings and not for a single string.
In Python, a string is very similar to a list of individual characters, and that's how the decorated function is treating it. If you want to process a single string, you can turn it into a list of only one ['string']. Or rewrite the decorator so that it checks whether the argument is a list or a string, and then handles the situation accordingly!
@ Thanks again! That is what I wanted to know. That I will never use the decorated function anymore. Instead, I will use the decorator functionality.
I do not understand how your decorator function (turn_into_another_function) returns the function (another_function) which is not declared yet in it's global scope. For me, I have to define the another_function above all. Only then I get the decorator works. Else, I get that function not defined error!!. Please correct me if I'm wrong.
That's correct-it's a bug in the video, so to say. The reason that it works in the video is that `another_function()` was already defined in the workspace because of what I did before. But if you run it from scratch you'll indeed get this error. This has been fixed in the notebook that you can find under the link below the video.
@ thank you
Hello Sebastiaan Mathôt,
Thank you so much for this great tutorial. I don't quite understand one syntax in @mapper, func(value) for value in list_of_values, what is func(value)?
Also, I believe camelcase is turn string_like_this to stringLikeThis. So this is my camelcase func
def camelcase(text):
a=[word for word in text.split('_')]
return a[0].lower()+''.join([a[i].title() for i in range(1, len(a))])
fnc(value) is the actual function call, where fnc is the decorated function, and value is the function argument. And this is embedded in a list comprehension so that fnc is called once for each value from list_of_values. Does that make sense? And you're right about camelCase :-)
can I understand this way? func(value) is actually calling camelcase(s)? decorator is complicated.
Yes, exactly!
Too many ads interrupts the instruction.
Great video, but I get an error when executing the first example:
line 3, in turn_into_another_function
return another_function
NameError: name 'another_function' is not defined
I already checked for spelling mistakes, but everything seems to be fine. Can anyone help me with that?
Ah, thanks for pointing this out! I fixed the notebook: osf.io/szwhk/
I wonder how it worked out in the video (2:40). You are defining another_function() after applying the decorator. Why didn't it give a NameError?
That's simply because another_function had already been defined in the workspace during a previous execution of the cell. But when running from an empty workspace it indeed couldn't work.
I keep getting this error:
# python test.py
Traceback (most recent call last):
File "test.py", line 6, in
a_function = turn_into_another_function(a_function)
File "test.py", line 2, in turn_into_another_function
return another_function
NameError: global name 'another_function' is not defined
This is what the code looks like:
def turn_into_another_function(fnc):
return another_function
def a_function():
print('a function')
a_function = turn_into_another_function(a_function)
def another_function():
print('another function')
a_function()
There was a bug in the notebook which I hadn't noticed! The fixed notebook is here: osf.io/szwhk/
There was a bug in the original notebook, but it's fixed now! osf.io/szwhk/
Is this related to assert
I'm assuming that you're referring to the `assert` statement, which is a kind of sanity check that crashes the program when a certain condition is not met. So no, that's not really related to decorators!
This is a really good tutorial but I still dont get it unfortunately
👍
Function, a function, another function, function, function decorator dizzy.
But why would you do this?
Why not just update the camelcase function to accept list instead?
In general, decorators allow you to apply some common functionality to many functions, without having to explicitly implement this in each of the functions. So it's about modularity. Of course, this camelcase example is too trivial to really highlight the usefulness of decorators. But imagine for example a 'memoization' decorator that caches the results of a time-consuming function.
Thank you!