title
Python Tutorial: Decorators - Dynamically Alter The Functionality Of Your Functions

description
In this Python tutorial, we will be learning about decorators. Decorators are a way to dynamically alter the functionality of your functions. So for example, if you wanted to log information when a function is run, you could use a decorator to add this functionality without modifying the source code of your original function. So let's take a look at how these decorators work and a few ways in which we can use them. Let's get started. First-Class Functions Video: https://youtu.be/kr0mpwqttM0 Closures Video: https://youtu.be/swU3c34d2NQ The code from this video can be found at: https://github.com/CoreyMSchafer/code_snippets/tree/master/Decorators ✅ Support My Channel Through Patreon: https://www.patreon.com/coreyms ✅ Become a Channel Member: https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join ✅ One-Time Contribution Through PayPal: https://goo.gl/649HFY ✅ Cryptocurrency Donations: Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3 Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33 Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot ✅ Corey's Public Amazon Wishlist http://a.co/inIyro1 ✅ Equipment I Use and Books I Recommend: https://www.amazon.com/shop/coreyschafer ▶️ You Can Find Me On: My Website - http://coreyms.com/ My Second Channel - https://www.youtube.com/c/coreymschafer Facebook - https://www.facebook.com/CoreyMSchafer Twitter - https://twitter.com/CoreyMSchafer Instagram - https://www.instagram.com/coreymschafer/ #Python

detail
{'title': 'Python Tutorial: Decorators - Dynamically Alter The Functionality Of Your Functions', 'heatmap': [{'end': 168.963, 'start': 141.068, 'weight': 1}, {'end': 611.1, 'start': 564.432, 'weight': 0.736}, {'end': 1153.712, 'start': 1130.06, 'weight': 0.771}, {'end': 1690.679, 'start': 1660.818, 'weight': 0.747}], 'summary': 'Tutorial provides a comprehensive overview of python decorators, covering topics such as inner functions, closures, and their use cases, as well as the implementation and usage of decorators in python, including examples of using star args and star star quargs, implementing decorators using class and function decorators, and chaining multiple decorators together to apply multiple functionalities.', 'chapters': [{'end': 262.889, 'segs': [{'end': 28.462, 'src': 'embed', 'start': 0.229, 'weight': 0, 'content': [{'end': 4.375, 'text': "Hey everybody, how's it going? In this video, we're going to be learning about Python decorators.", 'start': 0.229, 'duration': 4.146}, {'end': 8, 'text': "We're going to be learning how decorators work and also when you would want to use them.", 'start': 4.735, 'duration': 3.265}, {'end': 11.565, 'text': 'So decorators are a slightly more advanced topic,', 'start': 8.541, 'duration': 3.024}, {'end': 15.79, 'text': "but we're going to walk through a few different examples so that we can understand exactly what's going on.", 'start': 11.565, 'duration': 4.225}, {'end': 23.377, 'text': "Now, if you haven't watched my videos on closures or first class functions, then you should probably give those videos a watch,", 'start': 16.391, 'duration': 6.986}, {'end': 28.462, 'text': "because they will explain a lot of the underlying concepts that I'm not going to spend a lot of time on here.", 'start': 23.377, 'duration': 5.085}], 'summary': 'Learn about python decorators and when to use them, with examples and prerequisite knowledge.', 'duration': 28.233, 'max_score': 0.229, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U229.jpg'}, {'end': 75.565, 'src': 'embed', 'start': 51.676, 'weight': 1, 'content': [{'end': 63.039, 'text': 'Now, closures allow us to take advantage of first class functions and return an inner function that remembers and has access to variables local to the scope in which they were created.', 'start': 51.676, 'duration': 11.363}, {'end': 68.802, 'text': "Now, if both of those definitions sound a little confusing, then let's go ahead and take a look at a quick example here.", 'start': 63.539, 'duration': 5.263}, {'end': 75.565, 'text': "And again, I'm not going to go as in-depth as I do in those videos, but let's just do a quick recap.", 'start': 69.362, 'duration': 6.203}], 'summary': 'Closures utilize first class functions to return inner functions with access to local variables.', 'duration': 23.889, 'max_score': 51.676, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U51676.jpg'}, {'end': 168.963, 'src': 'heatmap', 'start': 141.068, 'weight': 1, 'content': [{'end': 149.595, 'text': "So now when we execute this outer function, what it's going to do is it's going to return this inner function waiting to be executed.", 'start': 141.068, 'duration': 8.527}, {'end': 156.361, 'text': "So in order to illustrate this, I'm going to actually set this equal to a variable here called my func.", 'start': 149.975, 'duration': 6.386}, {'end': 162.242, 'text': 'So now my func is going to be equal to our inner function waiting to be executed.', 'start': 156.801, 'duration': 5.441}, {'end': 166.503, 'text': 'So now I can execute this just like any other function.', 'start': 162.662, 'duration': 3.841}, {'end': 168.963, 'text': "So I'll execute it a couple of times in a row here.", 'start': 166.523, 'duration': 2.44}], 'summary': 'Executing outer function returns inner function, illustrated by setting it to a variable and subsequently executing it multiple times.', 'duration': 27.895, 'max_score': 141.068, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U141068.jpg'}, {'end': 200.013, 'src': 'embed', 'start': 170.904, 'weight': 2, 'content': [{'end': 174.064, 'text': 'So you can see that it prints out our message variable multiple times.', 'start': 170.904, 'duration': 3.16}, {'end': 181.566, 'text': "So that's what a closure is because it remembers our message variable even after the outer function has finished executing.", 'start': 174.525, 'duration': 7.041}, {'end': 186.988, 'text': 'So we can see this in more detail if we pass in some arguments to our outer function.', 'start': 182.026, 'duration': 4.962}, {'end': 192.59, 'text': "So I'm going to have our outer function take in a variable here called msg.", 'start': 187.368, 'duration': 5.222}, {'end': 200.013, 'text': "And instead of hard coding in hi here to this message variable, I'm just going to set it equal to that argument and save that.", 'start': 193.071, 'duration': 6.942}], 'summary': 'Closure allows access to variable even after function execution. demonstrated by printing message variable multiple times and passing arguments to outer function.', 'duration': 29.109, 'max_score': 170.904, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U170904.jpg'}], 'start': 0.229, 'title': 'Inner functions and closures', 'summary': 'Provides an introduction to python decorators, first class functions, and closures, emphasizing their functionality and use cases. it also explains inner functions in javascript and the concept of closures, demonstrating their ability to retain access to outer function variables and create unique instances of inner functions based on passed-in arguments.', 'chapters': [{'end': 68.802, 'start': 0.229, 'title': 'Python decorators overview', 'summary': 'Provides an introduction to python decorators, explaining their functionality and when to use them, while referencing related topics such as closures and first class functions. it also encourages viewers to refer to previous videos for a more comprehensive understanding. the chapter emphasizes the ability of first class functions to treat functions like any other object and the use of closures to access variables local to their creation scope.', 'duration': 68.573, 'highlights': ['The chapter provides an introduction to Python decorators, explaining their functionality and when to use them, while referencing related topics such as closures and first class functions.', 'It also encourages viewers to refer to previous videos for a more comprehensive understanding.', 'The chapter emphasizes the ability of first class functions to treat functions like any other object and the use of closures to access variables local to their creation scope.']}, {'end': 170.464, 'start': 69.362, 'title': 'Javascript inner functions', 'summary': 'Explains the concept of inner functions in javascript, demonstrating how an outer function can create an inner function and access its local variables, and returning the inner function without executing it, allowing it to be stored in a variable and executed later.', 'duration': 101.102, 'highlights': ['The chapter explains the concept of inner functions in JavaScript, demonstrating how an outer function can create an inner function and access its local variables, and returning the inner function without executing it, allowing it to be stored in a variable and executed later.', 'An outer function with a local variable called message creates an inner function that has access to the message variable, which is referred to as a free variable.', 'Executing the outer function results in the inner function being returned without being executed, allowing it to be stored in a variable and executed at a later time.']}, {'end': 262.889, 'start': 170.904, 'title': 'Understanding closures in javascript', 'summary': 'Explains closures in javascript, demonstrating how they retain access to outer function variables and can be used to create multiple unique instances of inner functions based on passed-in arguments, as shown by printing specific messages for different inner functions.', 'duration': 91.985, 'highlights': ["The inner function in a closure retains access to the outer function's variables even after the outer function has finished executing, as demonstrated by the repeated printing of the message variable.", 'By passing arguments to the outer function, unique instances of inner functions can be created, allowing for custom messages to be printed based on the passed-in values.', "The value of the message variable in the inner function is solely dependent on the argument passed to the outer function, showcasing the direct relationship between the outer function's input and the inner function's behavior."]}], 'duration': 262.66, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U229.jpg', 'highlights': ['The chapter provides an introduction to Python decorators, explaining their functionality and when to use them, while referencing related topics such as closures and first class functions.', 'The chapter explains the concept of inner functions in JavaScript, demonstrating how an outer function can create an inner function and access its local variables, and returning the inner function without executing it, allowing it to be stored in a variable and executed later.', "The inner function in a closure retains access to the outer function's variables even after the outer function has finished executing, as demonstrated by the repeated printing of the message variable."]}, {'end': 489.773, 'segs': [{'end': 326.077, 'src': 'embed', 'start': 263.11, 'weight': 0, 'content': [{'end': 270.936, 'text': 'And instead of printing out, setting message and printing that out, we can just come down here and directly print out that message there.', 'start': 263.11, 'duration': 7.826}, {'end': 273.758, 'text': 'And if I run that, you can see that that still works also.', 'start': 271.136, 'duration': 2.622}, {'end': 280.483, 'text': 'Okay, so that is a quick recap of closures, and I go into closures more in depth in the actual closures video.', 'start': 274.298, 'duration': 6.185}, {'end': 282.985, 'text': "But now let's move on to decorators.", 'start': 280.903, 'duration': 2.082}, {'end': 286.167, 'text': "So decorators are very similar to what we've already done here.", 'start': 283.285, 'duration': 2.882}, {'end': 288.449, 'text': 'Okay, so what is a decorator?', 'start': 286.648, 'duration': 1.801}, {'end': 297.956, 'text': 'A decorator is just a function that takes another function as an argument, adds some kind of functionality and then returns another function.', 'start': 288.829, 'duration': 9.127}, {'end': 302.66, 'text': 'All of this without altering the source code of the original function that you passed in.', 'start': 298.436, 'duration': 4.224}, {'end': 311.346, 'text': "So to show an example of this, let me grab some code here from my snippets that's almost identical to the example that we just looked at here.", 'start': 303.16, 'duration': 8.186}, {'end': 316.29, 'text': 'Now, actually, this is identical to the example that we just looked at,', 'start': 312.507, 'duration': 3.783}, {'end': 326.077, 'text': "but except we've changed the naming of our outer function to decorator function and we've changed the name of our inner function to wrapper function.", 'start': 316.29, 'duration': 9.787}], 'summary': 'Closures and decorators explained with examples in a coding tutorial.', 'duration': 62.967, 'max_score': 263.11, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U263110.jpg'}, {'end': 438.157, 'src': 'embed', 'start': 411.937, 'weight': 4, 'content': [{'end': 418.12, 'text': 'And just as a reminder, our decorator function here returns this wrapper that is waiting to be executed.', 'start': 411.937, 'duration': 6.183}, {'end': 425.725, 'text': 'So now this decorated display variable is actually equal to our wrapper function that is waiting to be executed.', 'start': 418.581, 'duration': 7.144}, {'end': 432.171, 'text': "And when it's executed, it just executes the original function that we passed in and returns it.", 'start': 426.205, 'duration': 5.966}, {'end': 438.157, 'text': 'So now I can run this decorated display variable just like any other function.', 'start': 432.572, 'duration': 5.585}], 'summary': 'Decorator function returns a wrapper waiting to be executed.', 'duration': 26.22, 'max_score': 411.937, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U411937.jpg'}], 'start': 263.11, 'title': 'Decorators in python', 'summary': 'Introduces closures and decorators, explaining that closures allow the direct printing of a message and decorators are functions that add functionality to another function without altering its source code. it also explains the concept of decorators in python, demonstrating how to modify a function by accepting another function as an argument and executing it within a wrapper function, thus illustrating the concept of decorators. additionally, it covers the concept of decorator function and wrapper, demonstrating how a decorator function passes in a display function to create a wrapper function that executes the original function, resulting in the display function running.', 'chapters': [{'end': 326.077, 'start': 263.11, 'title': 'Closures and decorators', 'summary': 'Introduces closures and decorators, explaining that closures allow the direct printing of a message and decorators are functions that add functionality to another function without altering its source code.', 'duration': 62.967, 'highlights': ['Decorators are functions that take another function as an argument, add functionality, and return another function, without altering the source code of the original function.', 'Closures allow the direct printing of a message without the need to set the message and then print it out.', 'The chapter provides a quick recap of closures, and then delves into decorators which are explained to be very similar to closures.']}, {'end': 387.003, 'start': 326.457, 'title': 'Understanding decorators in python', 'summary': 'Explains the concept of decorators in python, demonstrating how to modify a function by accepting another function as an argument and executing it within a wrapper function, thus illustrating the concept of decorators.', 'duration': 60.546, 'highlights': ['Modifying a function by accepting another function as an argument and executing it within a wrapper function, thus illustrating the concept of decorators.', 'Demonstrating a simple decorator in Python by executing the original function within a wrapper function and returning the result.']}, {'end': 489.773, 'start': 387.283, 'title': 'Decorator function and wrapper', 'summary': 'Explains the concept of decorator function and wrapper, demonstrating how a decorator function passes in a display function to create a wrapper function that executes the original function, resulting in the display function running.', 'duration': 102.49, 'highlights': ['The decorated display variable is actually equal to our wrapper function that is waiting to be executed.', 'The wrapper function executes the original function, which in this case is display, and just returns that.', 'The decorator function passes in our display function to create a wrapper function that executes the original function, resulting in the display function running.']}], 'duration': 226.663, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U263110.jpg', 'highlights': ['Decorators are functions that take another function as an argument, add functionality, and return another function, without altering the source code of the original function.', 'Modifying a function by accepting another function as an argument and executing it within a wrapper function, thus illustrating the concept of decorators.', 'Closures allow the direct printing of a message without the need to set the message and then print it out.', 'The chapter provides a quick recap of closures, and then delves into decorators which are explained to be very similar to closures.', 'The decorated display variable is actually equal to our wrapper function that is waiting to be executed.']}, {'end': 731.789, 'segs': [{'end': 527.484, 'src': 'embed', 'start': 490.274, 'weight': 0, 'content': [{'end': 497.218, 'text': 'So I know with these decorators sometimes it can be hard to keep track of the wrappers and the original functions and things like that, but hopefully,', 'start': 490.274, 'duration': 6.944}, {'end': 500.141, 'text': "as the video goes on, we'll get more and more comfortable with this.", 'start': 497.218, 'duration': 2.923}, {'end': 505.986, 'text': 'Okay, so, now that we have a basic decorator example here, why would we want to do something like this?', 'start': 500.781, 'duration': 5.205}, {'end': 515.953, 'text': 'So decorating our functions allows us to easily add functionality to our existing functions by adding that functionality inside of our wrapper.', 'start': 506.426, 'duration': 9.527}, {'end': 522.22, 'text': 'So, for example, here, Without modifying our original display function in any way,', 'start': 516.315, 'duration': 5.905}, {'end': 526.383, 'text': 'I can come inside of our wrapper and add any kind of code that I want.', 'start': 522.22, 'duration': 4.163}, {'end': 527.484, 'text': 'So, for example,', 'start': 526.763, 'duration': 0.721}], 'summary': 'Decorators make it easy to add functionality to existing functions without modifying them.', 'duration': 37.21, 'max_score': 490.274, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U490274.jpg'}, {'end': 611.1, 'src': 'heatmap', 'start': 555.526, 'weight': 2, 'content': [{'end': 563.672, 'text': 'we can see that it executed our wrapper message before it executed our original display function and printed out that message.', 'start': 555.526, 'duration': 8.146}, {'end': 569.335, 'text': "So, so far I've been using this syntax in order to create our decorators.", 'start': 564.432, 'duration': 4.903}, {'end': 575.979, 'text': 'But most of you may have come to this video expecting to see something that looks something more like this.', 'start': 569.835, 'duration': 6.144}, {'end': 579.642, 'text': 'Now this is how we usually see decorators in Python.', 'start': 576.54, 'duration': 3.102}, {'end': 588.466, 'text': 'But this is the same thing as setting our original function equal to the function wrapped within our decorator.', 'start': 580.202, 'duration': 8.264}, {'end': 598.132, 'text': 'So having this syntax here would be the same thing as saying that I want my display function equal to this decorator function,', 'start': 588.907, 'duration': 9.225}, {'end': 600.313, 'text': 'with our original function passed in.', 'start': 598.132, 'duration': 2.181}, {'end': 611.1, 'text': 'So now anytime if I use this syntax here, anytime I run this function, then it will have that new functionality added on.', 'start': 600.793, 'duration': 10.307}], 'summary': 'Demonstrates decorator syntax and its functionality in python.', 'duration': 24.116, 'max_score': 555.526, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U555526.jpg'}, {'end': 652.746, 'src': 'embed', 'start': 627.196, 'weight': 3, 'content': [{'end': 632.338, 'text': "especially whenever we chain multiple decorators together, and we'll look a little bit at that later on.", 'start': 627.196, 'duration': 5.142}, {'end': 639.221, 'text': 'So again, just one more time if I put this decorator symbol above the function like this,', 'start': 632.838, 'duration': 6.383}, {'end': 647.724, 'text': 'then it is exactly the same as saying that I want my display function now equal to this decorator function,', 'start': 639.221, 'duration': 8.503}, {'end': 652.746, 'text': 'with this display function passed in like this.', 'start': 648.924, 'duration': 3.822}], 'summary': 'Chaining decorators and function modification demonstrated in python.', 'duration': 25.55, 'max_score': 627.196, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U627196.jpg'}], 'start': 490.274, 'title': 'Python decorators', 'summary': "Discusses the usage and implementation of decorators in python, highlighting how they can be used to easily add functionality to existing functions without modifying the original function, aiming to increase the audience's comfort with decorators. it also demonstrates the syntax, functionality, and limitations while showcasing the application of decorators to multiple functions.", 'chapters': [{'end': 527.484, 'start': 490.274, 'title': 'Decorators in python', 'summary': "Discusses the usage of decorators in python, highlighting how they can be used to easily add functionality to existing functions without modifying the original function, aiming to increase the audience's comfort with decorators.", 'duration': 37.21, 'highlights': ['Decorators in Python allow easy addition of functionality to existing functions without modifying the original function, increasing flexibility and reusability.', "The video aims to increase the audience's comfort with decorators as it progresses, addressing the initial difficulty in keeping track of wrappers and original functions."]}, {'end': 731.789, 'start': 527.484, 'title': 'Python decorators', 'summary': 'Discusses the implementation of decorators in python, demonstrating the syntax, functionality, and limitations, and also showcasing the application of decorators to multiple functions.', 'duration': 204.305, 'highlights': ['The chapter begins by demonstrating the syntax for creating decorators and how to apply them to functions, showing the execution of the wrapper message before the original display function.', 'The use of the decorator symbol above the function and setting the original function equal to the function wrapped within the decorator is explained as functionally equivalent, with the latter being easier to read, especially when chaining multiple decorators together.', 'The video also delves into the limitations of decorators when the original function takes in arguments, showcasing an error when attempting to apply the same decorator to a function that takes arguments.']}], 'duration': 241.515, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U490274.jpg', 'highlights': ['Decorators in Python allow easy addition of functionality to existing functions without modifying the original function, increasing flexibility and reusability.', "The video aims to increase the audience's comfort with decorators as it progresses, addressing the initial difficulty in keeping track of wrappers and original functions.", 'The chapter begins by demonstrating the syntax for creating decorators and how to apply them to functions, showing the execution of the wrapper message before the original display function.', 'The use of the decorator symbol above the function and setting the original function equal to the function wrapped within the decorator is explained as functionally equivalent, with the latter being easier to read, especially when chaining multiple decorators together.', 'The video also delves into the limitations of decorators when the original function takes in arguments, showcasing an error when attempting to apply the same decorator to a function that takes arguments.']}, {'end': 916.416, 'segs': [{'end': 778.484, 'src': 'embed', 'start': 732.309, 'weight': 0, 'content': [{'end': 739.598, 'text': 'And the error down here says that the wrapper function takes zero positional arguments, but that two were given.', 'start': 732.309, 'duration': 7.289}, {'end': 750.107, 'text': 'So what we need is we need to be able to pass any number of positional or keyword arguments to our wrapper and have it execute our original function with those arguments.', 'start': 740.018, 'duration': 10.089}, {'end': 757.414, 'text': 'Now the way that we can do this is by adding star args and star star quargs to our wrapper function.', 'start': 750.568, 'duration': 6.846}, {'end': 765.658, 'text': 'So if I come up here to our wrapper function and type in star args and star star quargs,', 'start': 757.814, 'duration': 7.844}, {'end': 770.12, 'text': 'and then I also want to pass these into our original function.', 'start': 765.658, 'duration': 4.462}, {'end': 778.484, 'text': 'Now you can actually call args and quargs anything that you want, but by convention in Python, these are usually the names that people go with.', 'start': 770.66, 'duration': 7.824}], 'summary': 'Wrapper function should take any number of positional or keyword arguments to execute original function.', 'duration': 46.175, 'max_score': 732.309, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U732309.jpg'}, {'end': 845.81, 'src': 'embed', 'start': 800.032, 'weight': 2, 'content': [{'end': 805.138, 'text': 'Okay, so now that we have these function decorators working with multiple examples,', 'start': 800.032, 'duration': 5.106}, {'end': 808.382, 'text': 'let me also show you another syntax that you might see from time to time.', 'start': 805.138, 'duration': 3.244}, {'end': 814.328, 'text': 'So some people like to use classes as decorators instead of using functions as decorators.', 'start': 808.922, 'duration': 5.406}, {'end': 817.933, 'text': "So let's go ahead and take a look at an example of that.", 'start': 814.749, 'duration': 3.184}, {'end': 820.734, 'text': "So let's just take this example from above.", 'start': 818.493, 'duration': 2.241}, {'end': 827.237, 'text': "here this decorator function and let's turn this into a class decorator that has the exact same functionality.", 'start': 820.734, 'duration': 6.503}, {'end': 835.621, 'text': "So I'm just going to create a new class here, and instead of decorator function, I'm going to call this decorator class.", 'start': 827.657, 'duration': 7.964}, {'end': 838.602, 'text': "And I'm just going to do an object there.", 'start': 836.181, 'duration': 2.421}, {'end': 845.81, 'text': 'Okay, now when we passed in our original function to our decorator function, we did that using an argument.', 'start': 839.142, 'duration': 6.668}], 'summary': 'Using classes as decorators instead of functions for multiple examples.', 'duration': 45.778, 'max_score': 800.032, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U800032.jpg'}, {'end': 916.416, 'src': 'embed', 'start': 873.604, 'weight': 4, 'content': [{'end': 878.828, 'text': "Now what that's going to do is it's going to tie our function with the instance of this class.", 'start': 873.604, 'duration': 5.224}, {'end': 888.955, 'text': 'Okay. and lastly, how do we mimic the functionality here with the wrapper adding some functionality to our original function?', 'start': 879.308, 'duration': 9.647}, {'end': 894.44, 'text': "And the way that we're going to do that within our class is we're going to implement this call method.", 'start': 889.436, 'duration': 5.004}, {'end': 897.642, 'text': 'And the call method is another double underscore method.', 'start': 894.66, 'duration': 2.982}, {'end': 905.668, 'text': "So it's double underscore call and we're going to pass in self and we're also going to pass in these args and quarks,", 'start': 898.042, 'duration': 7.626}, {'end': 910.051, 'text': 'because this is going to behave just like our wrapper function behaved.', 'start': 905.668, 'duration': 4.383}, {'end': 916.416, 'text': "Okay, so now I'm just going to grab this code from the wrapper function up here and paste this in.", 'start': 910.511, 'duration': 5.905}], 'summary': 'Tying function with class instance and implementing call method.', 'duration': 42.812, 'max_score': 873.604, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U873604.jpg'}], 'start': 732.309, 'title': 'Using python decorators', 'summary': 'Discusses using star args and star star quargs to pass any number of positional or keyword arguments, demonstrates using classes as decorators, and explains implementing the call method in python classes.', 'chapters': [{'end': 799.432, 'start': 732.309, 'title': 'Using star args and star star quargs', 'summary': 'Discusses using star args and star star quargs to pass any number of positional or keyword arguments to a wrapper function, allowing it to execute the original function with those arguments, as demonstrated by the code.', 'duration': 67.123, 'highlights': ['By adding star args and star star quargs to the wrapper function, any number of positional or keyword arguments can be passed, enabling the execution of the original function with those arguments.', 'The use of star args and star star quargs in Python allows the acceptance of arbitrary numbers of positional or keyword arguments for functions, ensuring functionality with both original and wrapper functions.']}, {'end': 873.244, 'start': 800.032, 'title': 'Using classes as function decorators', 'summary': 'Demonstrates how to use classes as decorators, providing an alternative syntax to function decorators and explaining the process of converting a decorator function into a class decorator.', 'duration': 73.212, 'highlights': ['The process of converting a decorator function into a class decorator is demonstrated, emphasizing the creation of a new class and the utilization of an init method to pass the original function into the decorator class.', 'The chapter explains an alternative syntax for using classes as decorators, providing insight into how some individuals prefer this approach over using functions as decorators.']}, {'end': 916.416, 'start': 873.604, 'title': 'Implementing call method in python classes', 'summary': 'Discusses implementing the call method in python classes to tie a function with an instance of a class, mimic the functionality of a wrapper function, and pass in args and quarks to behave like the wrapper function.', 'duration': 42.812, 'highlights': ['Tying a function with an instance of a class', 'Mimicking the functionality of a wrapper function', 'Passing in args and quarks to behave like the wrapper function']}], 'duration': 184.107, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U732309.jpg', 'highlights': ['By adding star args and star star quargs to the wrapper function, any number of positional or keyword arguments can be passed, enabling the execution of the original function with those arguments.', 'The use of star args and star star quargs in Python allows the acceptance of arbitrary numbers of positional or keyword arguments for functions, ensuring functionality with both original and wrapper functions.', 'The process of converting a decorator function into a class decorator is demonstrated, emphasizing the creation of a new class and the utilization of an init method to pass the original function into the decorator class.', 'The chapter explains an alternative syntax for using classes as decorators, providing insight into how some individuals prefer this approach over using functions as decorators.', 'Tying a function with an instance of a class', 'Mimicking the functionality of a wrapper function', 'Passing in args and quarks to behave like the wrapper function']}, {'end': 1427.157, 'segs': [{'end': 1005.788, 'src': 'embed', 'start': 965.25, 'weight': 0, 'content': [{'end': 970.752, 'text': 'So we got the exact same result but only using the class as the decorator instead of the function.', 'start': 965.25, 'duration': 5.502}, {'end': 976.394, 'text': "So I hope that's not too confusing, but I wanted to show both ways that this is implemented,", 'start': 971.092, 'duration': 5.302}, {'end': 981.636, 'text': 'because some people like to use classes instead of functions for their decorators.', 'start': 976.394, 'duration': 5.242}, {'end': 984.217, 'text': 'so I wanted you to be aware that that was an option.', 'start': 981.636, 'duration': 2.581}, {'end': 989.22, 'text': "But for the rest of the tutorial, I'm going to continue using the function decorators,", 'start': 984.457, 'duration': 4.763}, {'end': 995.403, 'text': "because those are the ones that I see more often and they're also the ones that I think that you'll run into more often.", 'start': 989.22, 'duration': 6.183}, {'end': 999.485, 'text': "So I'm going to go ahead and delete this class decorator here.", 'start': 995.803, 'duration': 3.682}, {'end': 1005.788, 'text': 'But I just wanted you to know that that was a possibility and you should look into them,', 'start': 1000.485, 'duration': 5.303}], 'summary': 'Showing two ways to implement decorators: class and function. function decorators are more common and likely to be encountered.', 'duration': 40.538, 'max_score': 965.25, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U965250.jpg'}, {'end': 1058.178, 'src': 'embed', 'start': 1031.539, 'weight': 8, 'content': [{'end': 1036.182, 'text': 'But where a lot of people get tripped up is when they try to think of some practical examples for decorators.', 'start': 1031.539, 'duration': 4.643}, {'end': 1039.565, 'text': "So let's go ahead and look at a couple of practical examples,", 'start': 1036.723, 'duration': 2.842}, {'end': 1045.429, 'text': "and maybe they'll give you some ideas for how you can use decorators within your projects.", 'start': 1039.565, 'duration': 5.864}, {'end': 1052.815, 'text': 'So let me go to my snippets code here and grab some of these practical examples here.', 'start': 1045.848, 'duration': 6.967}, {'end': 1058.178, 'text': "So I'm just going to go ahead and grab these and paste them in over here.", 'start': 1052.835, 'duration': 5.343}], 'summary': 'Practical examples of decorators provided to inspire project usage.', 'duration': 26.639, 'max_score': 1031.539, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1031539.jpg'}, {'end': 1104.709, 'src': 'embed', 'start': 1076.233, 'weight': 1, 'content': [{'end': 1083.077, 'text': "Let's say that I want to keep track of how many times a specific function is run and what arguments were passed to that function.", 'start': 1076.233, 'duration': 6.844}, {'end': 1089.461, 'text': "So let's kind of walk through this my logger decorator here and see exactly what's going on.", 'start': 1083.538, 'duration': 5.923}, {'end': 1093.304, 'text': 'So you can see that we are passing in our original function.', 'start': 1089.902, 'duration': 3.402}, {'end': 1104.709, 'text': 'then we are importing the logging module and setting up a log file that matches the name of our original function, and then, right here,', 'start': 1093.944, 'duration': 10.765}], 'summary': "The logger decorator tracks the function's execution and arguments.", 'duration': 28.476, 'max_score': 1076.233, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1076233.jpg'}, {'end': 1153.712, 'src': 'heatmap', 'start': 1130.06, 'weight': 0.771, 'content': [{'end': 1137.584, 'text': 'and then, lastly, we are returning our wrapper function, which allows us to run all of this with the added functionality.', 'start': 1130.06, 'duration': 7.524}, {'end': 1141.325, 'text': "okay, so let's actually look at this being run with an example.", 'start': 1137.584, 'duration': 3.741}, {'end': 1148.768, 'text': "so I'm going to go ahead and copy this decorator here and I'm going to come down here to our display info function,", 'start': 1141.325, 'duration': 7.443}, {'end': 1153.712, 'text': "and for now I'm just gonna copy that out and save that.", 'start': 1148.768, 'duration': 4.944}], 'summary': 'Returning a wrapper function to run with added functionality.', 'duration': 23.652, 'max_score': 1130.06, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1130060.jpg'}, {'end': 1242.001, 'src': 'embed', 'start': 1193.05, 'weight': 3, 'content': [{'end': 1204.582, 'text': 'So you can imagine how repetitive and error-prone it would be if you wanted to add that functionality to multiple functions and tried to manually add in that logging code within each individual function.', 'start': 1193.05, 'duration': 11.532}, {'end': 1213.772, 'text': 'The decorator allows us to maintain our added functionality in one location and easily apply it anywhere that we want within our code base.', 'start': 1204.982, 'duration': 8.79}, {'end': 1223.155, 'text': 'okay. now, another easy, practical example that people sometimes use decorators for is for timing how long functions run.', 'start': 1214.332, 'duration': 8.823}, {'end': 1228.536, 'text': 'so let me go ahead and walk through this timing function here.', 'start': 1223.155, 'duration': 5.381}, {'end': 1230.837, 'text': 'now you can see that this is pretty similar.', 'start': 1228.536, 'duration': 2.301}, {'end': 1242.001, 'text': "we're passing in our original function and we are importing the time module, and within our wrapper function we set the beginning time as t1..", 'start': 1230.837, 'duration': 11.164}], 'summary': 'Using decorators to add functionality and time functions for efficiency.', 'duration': 48.951, 'max_score': 1193.05, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1193050.jpg'}, {'end': 1358.749, 'src': 'embed', 'start': 1334.873, 'weight': 4, 'content': [{'end': 1343.539, 'text': "So for this example, I'm just gonna use the two simple decorators that I have here, my timer and my logger.", 'start': 1334.873, 'duration': 8.666}, {'end': 1353.425, 'text': "What if I wanted to apply both of these decorators to one function? Well, it's just as easy as stacking the decorators one on top of each other.", 'start': 1343.559, 'duration': 9.866}, {'end': 1358.749, 'text': 'If I do my timer there, then I can also add my logger there.', 'start': 1353.806, 'duration': 4.943}], 'summary': 'Using multiple decorators is as simple as stacking them on top of each other.', 'duration': 23.876, 'max_score': 1334.873, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1334873.jpg'}], 'start': 917.037, 'title': 'Implementing python decorators', 'summary': 'Discusses implementing decorators using class and function decorators, practical examples, python decorators for logging, use of decorators to time function execution, and chaining multiple decorators together to apply multiple functionalities.', 'chapters': [{'end': 1052.815, 'start': 917.037, 'title': 'Decorator implementation and practical examples', 'summary': 'Discusses the implementation of decorators using both class and function decorators, and then explores practical examples to illustrate their usage within projects.', 'duration': 135.778, 'highlights': ['The chapter covers the implementation of decorators using both class and function decorators, demonstrating that they can achieve the same result while offering different options for implementation.', 'The tutorial continues with the use of function decorators due to their prevalence and practicality, ultimately deleting the class decorator to focus on function decorators.', 'The transcript delves into practical examples to illustrate how decorators can be utilized within projects, aiming to provide ideas for their application in real-world scenarios.']}, {'end': 1213.772, 'start': 1052.835, 'title': 'Python decorators for logging', 'summary': 'Discusses the use of decorators in python for logging, demonstrating an example where a decorator is used to track the execution of a specific function and its arguments, streamlining the functionality to easily apply it to multiple functions within the code base.', 'duration': 160.937, 'highlights': ['The decorator allows us to maintain added functionality in one location and easily apply it anywhere within our code base, mitigating repetitive and error-prone manual coding efforts.', 'Demonstration of using a decorator to track the execution of a specific function and its arguments, showcasing the streamlined application of the logging functionality.', 'Illustration of how decorators in Python can be used for logging to keep track of the number of times a specific function is run and the arguments passed to it, enhancing the maintainability and reusability of the code.']}, {'end': 1427.157, 'start': 1214.332, 'title': 'Using decorators for timing functions', 'summary': "Demonstrates how decorators can be used for timing the execution of functions and chaining multiple decorators together, showing examples of timing a function's execution and stacking decorators to apply multiple functionalities.", 'duration': 212.825, 'highlights': ["The chapter demonstrates how to use decorators for timing how long functions run, with an example of timing a function's execution.", 'It also shows how to chain decorators together to apply multiple functionalities, such as timing and logging, to one function.', 'The examples illustrate the process of applying decorators to time the execution of a function and the unexpected results that can occur when stacking decorators in the wrong order.']}], 'duration': 510.12, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U917037.jpg', 'highlights': ['The chapter covers the implementation of decorators using both class and function decorators, offering different options for implementation.', 'Illustration of how decorators in Python can be used for logging to keep track of the number of times a specific function is run and the arguments passed to it.', 'Demonstration of using a decorator to track the execution of a specific function and its arguments, showcasing the streamlined application of the logging functionality.', "The chapter demonstrates how to use decorators for timing how long functions run, with an example of timing a function's execution.", 'The examples illustrate the process of applying decorators to time the execution of a function and the unexpected results that can occur when stacking decorators in the wrong order.', 'The decorator allows us to maintain added functionality in one location and easily apply it anywhere within our code base, mitigating repetitive and error-prone manual coding efforts.', 'Demonstrates chaining decorators together to apply multiple functionalities, such as timing and logging, to one function.', 'The tutorial continues with the use of function decorators due to their prevalence and practicality, ultimately deleting the class decorator to focus on function decorators.', 'The transcript delves into practical examples to illustrate how decorators can be utilized within projects, aiming to provide ideas for their application in real-world scenarios.']}, {'end': 1819.789, 'segs': [{'end': 1484.628, 'src': 'embed', 'start': 1427.157, 'weight': 2, 'content': [{'end': 1444.2, 'text': 'this syntax of putting the decorator above this function is the same thing as saying display info equals my timer and then passing in display info to my timer.', 'start': 1427.157, 'duration': 17.043}, {'end': 1455.805, 'text': 'So if these two lines, this line here and this line here are the same, then what is the stacked version of this equivalent to?', 'start': 1444.6, 'duration': 11.205}, {'end': 1461.809, 'text': 'The stacked version is actually equivalent to just to keep chaining these together.', 'start': 1456.345, 'duration': 5.464}, {'end': 1467.414, 'text': 'So now we can do my logger and pass in all of that into my logger.', 'start': 1461.869, 'duration': 5.545}, {'end': 1473.519, 'text': 'So the lower ones here on the stack get executed first and then the higher ones.', 'start': 1467.854, 'duration': 5.665}, {'end': 1477.982, 'text': "Okay, so I know that this can look a little confusing, but let's go ahead and just step through this.", 'start': 1473.999, 'duration': 3.983}, {'end': 1484.628, 'text': "So we're passing our original display info function into my timer.", 'start': 1478.503, 'duration': 6.125}], 'summary': 'Using decorators allows chaining functions, executing lower ones first.', 'duration': 57.471, 'max_score': 1427.157, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1427157.jpg'}, {'end': 1641.582, 'src': 'embed', 'start': 1615.89, 'weight': 0, 'content': [{'end': 1625.374, 'text': "Okay, so how do we fix something like this? It's always a good idea to preserve the information of our original function whenever we use decorators.", 'start': 1615.89, 'duration': 9.484}, {'end': 1632.097, 'text': 'And we can preserve that information by using the functools module and the wraps decorator.', 'start': 1625.694, 'duration': 6.403}, {'end': 1636.7, 'text': "So I'm gonna go ahead at the top of this file, I'm gonna go ahead and import this.", 'start': 1632.498, 'duration': 4.202}, {'end': 1641.582, 'text': 'So it is from functools import wraps.', 'start': 1636.76, 'duration': 4.822}], 'summary': 'Preserve original function info using functools module and wraps decorator.', 'duration': 25.692, 'max_score': 1615.89, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1615890.jpg'}, {'end': 1690.679, 'src': 'heatmap', 'start': 1660.818, 'weight': 0.747, 'content': [{'end': 1670.646, 'text': 'And every wrapper for our decorators, we can just do this wraps decorator, and we want that to wrap the original function.', 'start': 1660.818, 'duration': 9.828}, {'end': 1678.633, 'text': "So now I'm also going to place this and decorate the wrapper function within timer also and save that.", 'start': 1671.027, 'duration': 7.606}, {'end': 1690.679, 'text': "So now if I come back down here and I rerun the single decorated example like I did before, so I'm going to comment all of those out.", 'start': 1679.073, 'duration': 11.606}], 'summary': 'Using wraps decorator to wrap original function within timer', 'duration': 29.861, 'max_score': 1660.818, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1660818.jpg'}, {'end': 1793.34, 'src': 'embed', 'start': 1752.698, 'weight': 1, 'content': [{'end': 1758.182, 'text': 'so we are using both of these decorators on a single function, like we were trying to do.', 'start': 1752.698, 'duration': 5.484}, {'end': 1761.205, 'text': "Okay, so I think that that's going to do it for this video.", 'start': 1758.903, 'duration': 2.302}, {'end': 1767.53, 'text': 'I really hope that this video helped in better understanding how decorators work and also how you might use them.', 'start': 1761.946, 'duration': 5.584}, {'end': 1774.195, 'text': "So you're going to run into decorators all the time when working with Python and also when you're working with third-party libraries.", 'start': 1768.111, 'duration': 6.084}, {'end': 1778.379, 'text': "So they're used a lot for class properties.", 'start': 1774.596, 'duration': 3.783}, {'end': 1783.867, 'text': "They're also used in routing for some web frameworks and all kinds of stuff.", 'start': 1778.419, 'duration': 5.448}, {'end': 1785.429, 'text': 'so hopefully after this video,', 'start': 1783.867, 'duration': 1.562}, {'end': 1793.34, 'text': "you'll be able to realize a little more of what's going on behind the scenes when you see these decorators and other code bases.", 'start': 1785.429, 'duration': 7.911}], 'summary': 'Understanding decorators in python for better coding practices and real-world applications.', 'duration': 40.642, 'max_score': 1752.698, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1752698.jpg'}], 'start': 1427.157, 'title': 'Python decorators in depth', 'summary': 'Delves into python decorators, covering their equivalence to function chaining and the usage of wraps decorator for preserving original function information, with illustrative code examples and precise execution order. it also emphasizes the importance of correct function execution and logging.', 'chapters': [{'end': 1484.628, 'start': 1427.157, 'title': 'Python decorators explained', 'summary': 'Explains the equivalence between using decorators and function chaining in python, using code examples to illustrate the concept and its execution order.', 'duration': 57.471, 'highlights': ['The stacked version of using decorators is equivalent to function chaining in Python.', 'The lower functions on the stack get executed before the higher ones.', 'The syntax of using decorators is equivalent to passing the function into another function, as illustrated by the example with my timer and display info.']}, {'end': 1819.789, 'start': 1485.208, 'title': 'Understanding python decorators', 'summary': 'Explains how to use wraps decorator to preserve original function information in python decorators, ensuring correct function execution and logging.', 'duration': 334.581, 'highlights': ['Using wraps decorator from the functools module to preserve original function information is crucial when using decorators, ensuring correct function execution and logging.', 'Decorators play a significant role in Python and are commonly used for class properties, routing in web frameworks, and various other applications.', 'Understanding decorators can be challenging, but watching the video multiple times and asking questions can help in grasping the concepts effectively.']}], 'duration': 392.632, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/FsAPt_9Bf3U/pics/FsAPt_9Bf3U1427157.jpg', 'highlights': ['Using wraps decorator to preserve original function info is crucial for correct execution and logging', 'Decorators play a significant role in Python for class properties, web routing, and more', 'The stacked version of decorators is equivalent to function chaining in Python', 'Syntax of using decorators is equivalent to passing the function into another function', 'Lower functions on the stack get executed before the higher ones']}], 'highlights': ['Decorators in Python allow easy addition of functionality to existing functions without modifying the original function, increasing flexibility and reusability.', 'The chapter covers the implementation of decorators using both class and function decorators, offering different options for implementation.', 'By adding star args and star star quargs to the wrapper function, any number of positional or keyword arguments can be passed, enabling the execution of the original function with those arguments.', 'The chapter provides a quick recap of closures, and then delves into decorators which are explained to be very similar to closures.', 'The tutorial continues with the use of function decorators due to their prevalence and practicality, ultimately deleting the class decorator to focus on function decorators.']}