DEV Community

Cover image for Let's do some decorating!
AnneMiriam
AnneMiriam

Posted on

Let's do some decorating!

Just like in JS, functions are first-class methods, meaning that they can be passed as an argument inside another function. And that's what Decorators do, they are essentially a function that you wrap around another function using the @ syntax.

In Python there are a number of built in functions that we see as decorators. Some like property can be used as a decorator or as a regular function.

Some common decorators include:

  • @classmethod
  • @property
  • @wraps
  • @abstractmethod
  • @staticmethod

So far, in my learning, I have really only used the 1st two examples above. Lets dive into them.

@classmethod
A class method binds to the class itself and not the instance, or object, of the class. Class methods take the class as the first argument, as "cls", rather than instance(self).
Class methods can modify a class state that applies then to all the instances of the class.
An example of a class method that we used:

create_table class method

In the create_table class method, we are creating a table that maps our Enemy class to a database called enemies. This new table will persist the attributes of all Enemy instances.

@property
Properties are attributes that are controlled by methods. We use a method to get the attribute and another method to set the attribute. The setter usually defines things like whether the attribute needs to be a string(str) or an integer(int), as well as if it's mutable or how long it can be.

The property method can be written as a regular function, like so:

property method

Or it can be used as a decorator, like this:

property decorator

The property() was created before the @decorator syntax, but the @property decorator is most often used today.

Now, a little bit about the other examples that I listed, but didn't learn in school.

@staticmethod
The static method, like the class method, belongs to the class itself, and not the instance of the class. But unlike @classmethod it does not have access to an instance or its attributes, and therefore cannot modify them. Hence, static - lacking in movement, action or change(Oxford Dictionary)!

static method, math example

What situation would you use @staticmethod:

  • when you need a function that is related to the class, but doesn't depend on the state of instances.
  • when you want to define a function that calls directly on the class.

@abstractmethod
We did not learn about the abstract base class, but they are what use the abstract method. An example of the use for the abstract method would be on something like a Shape class that is the base class for other classes of shapes:

Shape base abstract method

Above, Shape is an abstract base class with 2 defined @abstractmethod's, are and perimeter. The Circle and the Square classes, or subclasses, must implement the abstract methods that the base class defined. If the subclasses don't implement the methods then the class becomes an abstract base class as well. And in so doing, the user won't be able to create instances, they will get a TypeError.

When should you use @abstractmethod?

  • when a user wants to ensure that all subclasses of a base class implement certain methods and behaviors.
  • when a user wants to define a base class to provide common interfaces for a group of subclasses.

*Don't forget to import ABC and abstractmethod from abc. 😉

@wraps
The wraps decorator is a utility decorator that is part of Python's builtin functools module.
A function defined with the wraps decorator gets its original metadata, behavior, and attributes preserved.
Here are two examples of its use:

wraps decorator log function

==> Output: "Calling function add_numbers with args: (3, 5), kwargs: {}
Enter fullscreen mode Exit fullscreen mode

wraps decorator wrapper function

When to use @wraps?

  • when a user wants to define a decorator that wraps around another function, and you want the wrapped function to preserve the metadata of the original function.
    • in other words: To use the wraps decorator is to create custom decorators. These custom decorators wrap other functions with the original function.

*remember to import wraps from functools! 😉


Sources:
"classmethod() in python". @GeeksforGeeks, Sanchhaya Education Limited. Retrieved 4 Jan. 2024 from https://www.geeksforgeeks.org/classmethod-in-python/

Dr. Karhade, M. MD. PhD. "Most use python decorators: when to use and when not to". Published 22 March 2023. Retrieved on 5 Jan. 2024 from https://levelup.gitconnected.com/most-used-python-decorators-when-to-use-and-when-not-to-32b8f883ee43

Mwiti, D. "Python decorators tutorial". Published Oct. 2017. Retrieved on 4 Jan. 2023 from https://www.datacamp.com/tutorial/decorators-python

Top comments (0)