Lesson 06
Python Decorators — Wrap a Function with an Inner Function
Learn Python decorators as gift wrapping: square(getval) returns calculate(), pass the function not getval(), and reuse one wrapper for logging.
 - Gift wrapper =
square() - Wrapped gift =
calculate()
What you will learn
- A decorator takes a normal function as parameter
- It defines an inner function that adds behavior, then returns that inner function
mpr = square(getval)thenmpr()square(getval)()in one expression- Three separate helpers that each call
getval()— no wrapping - Playground uses
return 5.0, notinput()
How a decorator works
:
def FunctionName2():
# extra behavior
...
return FunctionName2FunctionName1is the decoratorFunctionName2is the inner function
Step-by-step code
Step 1 — Original function
def getval():
return 5.0This is just a normal function.
Step 2 — Decorator
def square(m):
def calculate():
n = m()
return n ** 2
return calculateNotice:
mstores the original functioncalculate()adds new behaviorreturn calculatesends back the wrapped function
Step 3 — Wrap it
mpr = square(getval)getval is passed without brackets because you are passing the function itself.
Full example with prints
def square(m):
print("Decorator Called")
def calculate():
print("Inner Function calling")
n = m()
res = n ** 2
return res
return calculate
mpr = square(getval) # decorator call — does not run calculate yet
print(type(mpr)) # function
res = mpr() # inner runs, getval runs
print("Square=", res)Run the full script in the playground below.
What happens internally?
Think of this like a factory.
 |
Decorator runs |
return calculate |
Gives back inner function |
mpr() |
Inner function executes |
m() |
Calls original getval() |
n ** 2 |
Returns square 25.0 |
Two ways to call it
Method 1 — Store the wrapped function
mpr = square(getval)
result = mpr()
print(result) # 25.0Easier to reuse multiple times.
Method 2 — One line
result = square(getval)()
print(result) # 25.0Creates and immediately executes the wrapper.
Both produce the same answer: 25.0.
The most common mistake
Students often write this:
Wrong:
square(getval())Here getval() runs immediately and returns 5.0. A float is not a function — the inner call m() would fail.
Correct:
square(getval)Here you pass the function object itself. The decorator can call m() later.
Without a decorator
Three helpers each call getval() for square, square-root, and cube. That works, but the extra math lives in new functions, not as a wrapper around getval:
def square_print():
n = getval()
print("square({})={}".format(n, n ** 2))
def squareroot_print():
n = getval()
print("squareroot({})={}".format(n, n ** 0.5))
def cube_print():
n = getval()
print("cube({})={}".format(n, n ** 3))Why do decorators exist?
Imagine 50 functions in your application. Every one needs logging.
Without decorators — repeated code:
def login():
print("Logging...")
...
def payment():
print("Logging...")
...With a decorator — one reusable wrapper:
@logger
def login():
...
@logger
def payment():
... instead of getval |
| One-line call? | square(getval)() |
30-second memory map
![original function decorator inner function result recap flow](data:image/svg+xml;charset=utf-8,%3Csvg%20font-family%3D%27ui-sans-serif%2C-apple-system%2Csystem-ui%2CArial%27%20width%3D%27100%25%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20320%20170%27%3E%20%3Crect%20width%3D%27320%27%20height%3D%27170%27%20rx%3D%2714%27%20fill%3D%27%23F8FAFC%27%2F%3E%20%3Crect%20x%3D%2760%27%20y%3D%2714%27%20width%3D%27200%27%20height%3D%2724%27%20rx%3D%276%27%20fill%3D%27%23DBEAFE%27%2F%3E%20%3Ctext%20x%3D%27160%27%20y%3D%2730%27%20font-size%3D%279%27%20font-weight%3D%27bold%27%20text-anchor%3D%27middle%27%20fill%3D%27%231D4ED8%27%3EOriginal%20Function%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%2750%27%20width%3D%27200%27%20height%3D%2724%27%20rx%3D%276%27%20fill%3D%27%23DDD6FE%27%2F%3E%20%3Ctext%20x%3D%27160%27%20y%3D%2766%27%20font-size%3D%279%27%20font-weight%3D%27bold%27%20text-anchor%3D%27middle%27%20fill%3D%27%235B21B6%27%3EDecorator%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%2786%27%20width%3D%27200%27%20height%3D%2724%27%20rx%3D%276%27%20fill%3D%27%23D1FAE5%27%2F%3E%20%3Ctext%20x%3D%27160%27%20y%3D%27102%27%20font-size%3D%279%27%20font-weight%3D%27bold%27%20text-anchor%3D%27middle%27%20fill%3D%27%23047857%27%3EInner%20Function%3C%2Ftext%3E%20%3Crect%20x%3D%2760%27%20y%3D%27122%27%20width%3D%27200%27%20height%3D%2724%27%20rx%3D%276%27%20fill%3D%27%23FDE68A%27%2F%3E%20%3Ctext%20x%3D%27160%27%20y%3D%27138%27%20font-size%3D%279%27%20font-weight%3D%27bold%27%20text-anchor%3D%27middle%27%20fill%3D%27%2392400E%27%3EResult%3C%2Ftext%3E%20%3C%2Fsvg%3E
Remember this sentence:
A decorator wraps a function, creates an inner function, and returns it so extra behavior can be added without modifying the original function.
Loading playground…
Check your understanding
Decorators overview quiz
A decorator is:
1 / 10