Join Jungwoo Ryoo for an in-depth discussion in this video Decorator example, part of Python: Design Patterns.
- Let's define our decorator by first making our decorator being transparent especially in terms of its name and doc string. So we use this special function @wraps and then we pass the function we are decorating so by doing this whatever we are using to decorate the function the effect of it will be transparent.
Now let's define what the decorator is doing by working on the inner function definition. First of all we'll try to grab the return value of the function that's actually being decorated. So we'll say ret, our variable assignment and whatever is being returned from the function we're getting in the decorator. And next we'll be doing our magic to further process whatever is being returned from the function being decorated.
So in this case we're simply adding a new tag which is blink tag in HTML. So type return. So we're not just returning whatever we got from the original function but with this additional string. Blink tag and then we'll append the blink tag to the returned value of the original function which is ret and then we'll close the tag, blink.
Now whatever we did will be returned by this statement, return decorator. Before we apply our decorator, let's try our plain function Hello, world! without the decorator and see what happens. So this function simply prints a string, Hello, world!, without the decorator. So we'll have our print statement here just to print the plain method, hello_world method. So just type print (hello_world()) and see what happens.
Let's run the script by going to the Tools and Build. So as expected, the Hello, world! string is displayed. Next, let's apply the decorator. And the way we apply the decorator is by just using this @, and then the name of the decorator, in this case make_blink. Now let's run the script again to check the effect of the decorator.
Go to Tools, Build, and as you can see the new text has been added to the original string. Now let's check if the function name is still the same name of the original function that's being decorated. So we have a little bit of typo here, still the same name. Okay, so we print the function name by typing hello_world.
__name and then we'll also print the doc string of the function print(hello_world .__doc__) now let's run the script again. Go to Tools, click on Build, and as you can see the function name is hello_world instead of being the name of the decorator. The name of the decorator in this case was make_blink.
And then the doc string of the decorator was Defines the decorator however whatever is being printed is Original function, as you can see and that was the doc string of the Original function which was right here. As you can see the decorator function can be used to add these additional features transparently to an existing function very easily.
- Understanding design patterns
- Best design practices: consistency, completeness, and correctness
- Working with creational patterns
- Working with structural patterns
- Working with behavioral patterns
Skill Level Intermediate
Q: In the strategy pattern example, why does the code keep executing the default function rather than the alternate?
A: The programming demonstration skips the step of defining what the strategy pattern should be when an alternate function name is provided
as an argument as shown below.