Decorators

Trying to make a small change to a python program in my job, I came across something I didnt know in python and only after reading this article (a couple of times) I managed to understand (ask me again in 3 weeks 🙂 The best definition I could find was actually from other blog reference and actually I think it was more clear to me.

“A decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.”

1 – Function returning a function:

In [7]: def greet(name): 
   ...:     return f"Hello, {name}!" 
   ...: def simon(func): 
   ...:     return func("Simon") 
   ...:                                                                                                                       

In [8]: simon(greet)                                                                                                          
Out[8]: 'Hello, Simon!'

simon is a function that has a function as argument, and calls that function with the argument “Simon”. So the function greet is receiving the argument “Simon” and returns a string with that name.

2 – Functions inside other functions:

In [9]: def respect(maybe): 
   ...:     def congrats(): 
   ...:         return "Congrats, bro!" 
   ...:     def insult(): 
   ...:         return "You're silly!" 
   ...:     if maybe == "yes": 
   ...:         return congrats 
   ...:     else: 
   ...:         return insult 
   ...:                                                                                                                       

In [10]: respect("hola")()                                                                                                    
Out[10]: "You're silly!"

In this case, to execute the returned function you need to use “()” at the end (because respect(“hola”) it is a function!): respect(“hola”)()

Keep in mind you return the function “congrats” and it is not executed. If you return “congrats()” then yes, you get the result of executing congrats.

3 – A function that takes another function and defines a function:

In [1]: def startstop(func): 
   ...:     def wrapper(): 
   ...:         print("Starting...") 
   ...:         func() 
   ...:         print("Finished!") 
   ...:     return wrapper 
   ...: def roll(): 
   ...:     print("Rolling on the floor laughing XD") 
   ...: roll = startstop(roll)                                                                                                

In [2]: roll()                                                                                                                
Starting...
Rolling on the floor laughing XD
Finished!

In [3]:        

This case is the same as before, need to use “()” to “execute” roll because it is a function.

4 – With decorator:

In [3]: def startstop(func): 
   ...:     def wrapper(): 
   ...:         print("Starting...") 
   ...:         func() 
   ...:         print("Finished!") 
   ...:     return wrapper 
   ...: @startstop 
   ...: def roll(): 
   ...:     print("Rolling on the floor laughing XD") 
   ...:                                                                                                                       

In [4]: roll()                                                                                                                
Starting...
Rolling on the floor laughing XD
Finished!

In [5]:          

So adding the decorator we avoid writing a line with nested functions. That in a more advanced case, it would make the code easier to read.

You can nest decorators and add arguments too.

Katmer

I love bread and I watch a lot of videos about cooking that come up randomly. And this one is something that caught my attention. This looks like it is a typical fried bread or pancake in central Asia. The video shows the Turkish version so I decided to give it a go:

Ingredients:

  • 2 glass of plain flour
  • 3/4 glass of water
  • 1 tsp of salt
  • 1/2 tsp of sugar
  • 75g butter melted
  • 1/4 glass vegetable oil

Process:

  • Mix salt and sugar in water. Add the water the flour and mix all well together.
  • Knead for 5 minutes. Let it rest and then knead again for a couple of minutes. Rest again for 15 minutes.
  • Knock the dough and form a rounded ball. Cut in four pieces and then each piece in two. In total you will have eight pieces. You can make it bigger though.
  • Round each dough ball and let is rest in a floured surface.
  • Mix the butter and vegetable oil.
  • This is the difficult part and is better to watch the video a couple of times. Be sure you have your surface properly floured (I am not used to) for the next step.
  • Using a rolling pin, try to make the thinnest layer you can, if rectangle shape, the better. Then spread some butter mix on it. Fold one third from the right side, spread some oil, fold the other third on top of the oiled one. Oil again. You should have a rectangle. Fold a third from the bottom, oil and fold finally from the top. You should have like a handkerchief .
  • In a medium/hot pan, with just a bit of oil, fry each unit until golden/crispy each side. If you are good, it will bubble up! (just a bit in my case)

It took me a bit and I struggled with rolling pin as I am not used to this kind of dough. But the result was good, very crispy! (I need much practice to reach the level of the video)