Clear, practical technology insights BSOD Code Lookup · Windows Error Code Lookup · Wi-Fi Troubleshooting · PC Troubleshooting Checklist

What Is Metaprogramming: Decorator in Python

Explore What Is Metaprogramming: Decorator in Python, including the main concepts, relevant details, and practical considerations.

Table of Contents

This updated guide examines What Is Metaprogramming: Decorator in Python and organizes the essential facts, background, and practical takeaways in clear American English.

What is Decorator in Python?

Python has an interesting feature called decorator. Decorator is a function that takes the input parameter as another function and extends the function to that function without changing its content.

This is also called metaprogramming, which simply means "Code generates code", meaning that I write a program and this program will generate, control other programs or do a part of the job right away. at the time of compilation.

Conditions for a Decorator

To understand decorators, you first need to review some of the basics in Python.

Functions are a very basic concept in programming in general. However, in Python, functions are also objects. The function names we declare are simply binding identifiers with these objects. A function object can also be associated with many different names. For example:

def first(msg): print(msg) first("Hello") second = first second("Hello")

When you run code, functionsfirstandsecondreturn the same output. Here,firstandsecondrefer to the same function object.

Stay tuned, functions can be passed as parameters to another function (similar to map, filter and reduce in Python).

Functions that take other functions as input parameters are called higher-order functions. For example:

def inc(x): return x + 1 def dec(x): return x - 1 def operate(func, x): result = func(x) return result

We call the function as follows.

>>> operate(inc,3) 4 >>> operate(dec,3) 2

Moreover, a function can return a different function.

def is_called(): def is_returned(): print("Hello") return is_returned new = is_called() #Outputs "Hello" new()

Here, is_returned () is a nested function, this function is accessed and returns the result every time we call is_called ().

For more information, you can refer to the lesson How to Use Closure in Python

Going back to Decorator , most fundamentally, Decorator is a function that can accept other functions, allowing you to run some code before or after the main function without changing the result.

def make_pretty(func): def inner(): print("I got decorated") func() return inner def ordinary(): print("I am ordinary")

Run code in Python shell:

>>> ordinary() I am ordinary >>> # Th? hàm decorate trong hàm ordinary >>> pretty = make_pretty(ordinary) >>> pretty() I got decorated I am ordinary

In the above example, make_pretty () is a decorator. When we call

pretty = make_pretty(ordinary)

then ordinary () is passed by decorator as a parameter and the function returns a pretty name .

You can see here, decorator has added a new function to the original function. Imagine it as a one-piece package. The decorators are the outer covering, the nature of the object decorator passed in as the parameter (the inner gift) does not change, but now it has an external decorator cover.

In general, here comes a function decorator and reassigns it:

ordinary = make_pretty(ordinary)

This is a common structure, so Python has a syntax to simplify this.

You can use the@symbol along with the name of the decorator function and place it above the definition of the decorator function. For example:

@make_pretty def ordinary(): print("I am ordinary")

equivalent to:

def ordinary(): print("I am ordinary") ordinary = make_pretty(ordinary)

This is a special syntax for implementing decorators.

Decorator function parameter

The above decorators are all quite simple and work with functions that don't have any parameters. Now try passing the parameter to the function returned by the decorator as follows:

def divide(a, b): return a/b

This function has two parameters, a and b, will report an error ifb=0.

>>> divide(2,5) 0.4 >>> divide(2,0) Traceback (most recent call last):. ZeroDivisionError: division by zero

When we call the function, it actually calls the function returned by decorator, so if it passes the parameter to this function, it will pass to the decorate function.

Now let's create a decorator to check if this is an error.

def smart_divide(func): def inner(a,b): print("I am going to divide",a,"and",b) if b == 0: print("Whoops! cannot divide") return return func(a,b) return inner @smart_divide def divide(a,b): return a/b

The program will returnNoneif an error arises.

>>> divide(2,5) I am going to divide 2 and 5 0.4 >>> divide(2,0) I am going to divide 2 and 0 Whoops! cannot divide

This is how to use the decorator function with parameters.

In addition, you can build a decorator with as many different parameters as you want, just use the syntax * args and ** kwargs.

def works_for_all(func): def inner(*args, **kwargs): print("I can decorate any function") return func(*args, **kwargs) return inner

When we call the function, we actually call the function returned by decorator, so if we pass the parameter to this function, it will pass to the decorate function.

String Decorator in Python

Many decorators can be made up of decorator strings in Python.

It means that a function can be decorate many times with the same or different decorators, just put the decorator in front of the function you want.

def star(func): def inner(*args, **kwargs): print("*" * 30) func(*args, **kwargs) print("*" * 30) return inner def percent(func): def inner(*args, **kwargs): print("%" * 30) func(*args, **kwargs) print("%" * 30) return inner @star @percent def printer(msg): print(msg) printer("Hello")

The program will return output:

****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Hello %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ******************************

Syntax:

@star @percent def printer(msg): print(msg)

equivalent to:

def printer(msg): print(msg) printer = star(percent(printer))

The order of decorator is also important, if you reverse:

@percent @star def printer(msg): print(msg)

The result will be different:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ****************************** Hello ****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Previous article: How to use Closure in Python

Next article: Declare @property in Python

FAQ

What is What Is Metaprogramming: Decorator in Python about?

It provides a structured overview of What is metaprogramming, explains the main context, and highlights practical takeaways for readers.

Why does this topic matter?

Understanding the main concepts helps readers evaluate the issue, avoid common mistakes, and make better-informed decisions.

How should readers use this information?

Use the guidance as a practical starting point, confirm details that may have changed, and follow current product, safety, or security recommendations.

Discussion

Reader Comments 0

Sign in with email or Google to join the discussion.