I really got confused on this, I had to practice a bit longer and I am still not fully sure. What I do know is using this first snippet from a lesson to do a basic return modification then creating a second decorator named ‘poop’ I was able to make it do more.
What I have learned is you put the @decorator name above the function you want decorated. I used functions with arguments, this can go way deeper with more advanced syntax. You can decorate multiple functions, but each time you do use the decorator it only decorates the following function, or it appears that way.
Use case, say you have a function named blah(text) this just simply returns text with a capital BLAH it, like ‘BLAH decorators are hard’. You would call this function using blah(‘decorators are hard’) and you would get the result above. Now say want to decorate this string, or I should say modify the output without changing the function blah() code because this may screw up other use cases, confusing I know.
So you simply create a decorator function, think of it like an addon on top of the blah() function. It will work if you write @decoratorname a line above the blah() function. Check out my code practice below, notice the decorators use an inbuilt function you create to modify and return the new result.
This may take awhile to wrap your head around, lots of up and down at the code to figure it out. Try removing the decorator call above the main function to see how they work, e.g. remove @poop from above function.
Now I am scratching my head with this still, like why use a decorator above the function and why not above the function call like @poop then next line print(poop_text(text)) . I was thinking more about this tonight while working and ‘think’ I see a use case, say I need a decorator that does the exact same thing like parse a data structure to return a specific format of data, now I can write just one decorator and use it on a bunch of different functions that extract or pull data with the exact same formatting instead of writing this multiple times in each function. Maybe, still not super confident on this.
Now the good news I see my next set of lessons are on ‘RECURSION’, if you don’t know this I love love love recursion. Technically I love any function that can loop without looping in the typical way and compactly, this reminds me of how lambdas are amazing too.
# This shit is confusing, and this code is just my own practice. # We need a string to display so enter one in text = input('Enter some text: ') # First decorator simply capitalizes, using this later def uppercase_decorator(func): def wrapper(text): #your code goes here return text.upper() return wrapper # Second decorator has more functionality and reverses the inputted string. Using this later def poop(func): def pooping(text): poop = list(reversed(text.split())) crap = ' '.join(poop) return crap return pooping # Putting decorator above custom function to modify, other wise the text would just be returned as it was entered. # First main function just returns plain text as entered of no decorator was above it, but we do have a decorator so it will be modified. @uppercase_decorator def display_text(text): return text # Now to actually print some text using the main function, it has a decorator before it so results will be modified. print(display_text(text)) @poop def poop_text(text): return text # Now to modify using a different decorator that reverses input string print(poop_text(text)) # Below some sample out put of this code. Enter some text: I like a late night drive I LIKE A LATE NIGHT DRIVE drive night late a like I
This link has some clear info on decorators https://www.geeksforgeeks.org/decorators-in-python/