DEV Community

Rohit Sanjay
Rohit Sanjay

Posted on

2 1

Decorator Factory - How to pass arguments to decorators

Skip to pass arguments to decorators if you already know what a decorator is

What is a decorator?

A decorator allows the user to add functionality to an existing function without modifying its structure.

For example,
We might need a way to authenticate an API call, and only then allow some data to be returned. We can streamline the authentication process by abstracting it into a decorator function.

Consider the following function that needs to be authenticated,

def foo(user_id):
   # perform some DB calls
   # perform some DB writes
   pass

We can use a decorator as follows,

def authenticate(func):
   def wrapper(*args, **kwargs):
       # perform auth checks
       if auth:
          func(*args, **kwargs)
       else:
          raise Exception('not authenticated')

   return wrapper

And hence, authenticating foo is as simple as,

@authenticate
def foo(user_id):
   # perform some DB calls
   # perform some DB writes
   pass

Pass arguments to decorators

Now that we have some knowledge of decorators, let us proceed to something more interesting. How would we pass arguments to decorators?

This is where it gets a little confusing - we will need to create a decorator factory that returns a particular decorator based on the arguments passed.

A simple use case could be when we want to call a function multiple times, but we do not want to write it in an explicit for loop, and neither do we want to use a for loop inside the function itself.

For example, we would want to call the function foo below, 10 times:

def foo():
   print("Hello World")

In this scenario, we can create a decorator factory that takes in a number and returns a decorator that calls a function a number of times.

def call(number):  # Decorator factory
    def decorator(func):
        def wraps(*args, **kwargs):
            for i in range(number):
                func(*args, **kwargs)

        return wraps

    return decorator

And to use the decorator factory above,

@call(10)
def foo():
   print("Hello World")

When we call foo now,

>>> foo()
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World

Thanks for reading! Please hit me up at sanjay.rohit2@gmail.com for any feedback :)

Image of AssemblyAI tool

Challenge Submission: SpeechCraft - AI-Powered Speech Analysis for Better Communication

SpeechCraft is an advanced real-time speech analytics platform that transforms spoken words into actionable insights. Using cutting-edge AI technology from AssemblyAI, it provides instant transcription while analyzing multiple dimensions of speech performance.

Read full post

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay