How to Use the Magical @staticmethod, @classmethod, and @property Decorators in Python | by Lynn Kwong

Photograph by Almos Bechtold on Unsplash

A decorator is a perform that takes one other perform as enter, extends its conduct, and returns a brand new perform as output. That is attainable as a result of, in Python, features are first-class objects, which suggests they are often handed as arguments to features and likewise be returned from features, simply as different forms of objects similar to string, int, or float. A decorator can be utilized to embellish a function or a class.

On this article, three particular decorators can be launched, particularly, @staticmethod, @classmethod, and @property. These “magical” decorators can develop into very helpful for our improvement work and make your code extra clear.

In Python and different programming languages, a static methodology is a technique that doesn’t require the creation of an occasion of a category. For Python, it implies that the primary argument of a static methodology will not be self, however an everyday positional or key phrase argument. Additionally, a static methodology can haven’t any arguments in any respect:

On this instance, __init__ is a reserved methodology of Python and works because the constructor for the category. get_number is an everyday occasion methodology of the category and requires the creation of an occasion. Particularly get_emergency_number is a static methodology as a result of it’s adorned with the @staticmethod decorator. Additionally, it doesn’t have self as the primary argument, which implies that it doesn’t require the creation of an occasion of the Cellphone class. Truly, get_emergency_number can simply work as a standalone perform. Nonetheless, it is smart and is intuitive to place it within the Cellphone class as a result of a cellphone ought to be capable to present the emergency quantity.

This can be a tremendous easy instance. Truly, in apply, if the Cellphone class has a nation property, the get_emergency_number methodology would develop into an occasion methodology as a result of it must entry the nation property to offer the right emergency quantity. Nonetheless, this instance ought to make it clear what’s a static methodology.

In Python, a category methodology is created with the @classmethod decorator and requires the category itself as the primary argument, which is written as cls. A category methodology usually works as a manufacturing facility methodology and returns an occasion of the category with equipped arguments. Nonetheless, it does not at all times must work as a manufacturing facility class and return an occasion. You possibly can create an occasion within the class methodology, do no matter you want, and don’t must return it:

On this instance, iphone is a category methodology because it’s adorned with the @classmethod decorator and has cls as the primary argument. It’s a manufacturing facility methodology right here and returns an occasion of the Cellphone class with the model preset to “Apple”.

Class strategies are very generally utilized in third-party libraries, for instance within the Scrapy web-scraping framework, it’s used to customize a crawler:

It’s extra advanced within the case of Scrapy, however the essence is identical. In your sensible work, should you use class strategies correctly, you possibly can scale back code redundancy dramatically and make your code extra readable and extra skilled. The important thing level to bear in mind is that you may create an occasion of the category based mostly on some particular arguments in a category methodology. On this manner, you don’t must repeatedly create cases elsewhere of your code and thus make your code DRYer.

Within the code snippet above, there’s a perform referred to as get_number which returns the variety of a Cellphone occasion. We are able to optimize this methodology a bit and return a formatted telephone quantity:

As we see, on this instance, once we attempt to get the variety of a cellphone, we don’t return it immediately however do some formatting earlier than returning it. This can be a excellent case for utilizing the @property decorator. In Python, with the @property decorator, you should utilize getter and setter to handle the attributes of your class cases very conveniently. The above code could be re-written with @propery like this:

Nonetheless, if we run the code like above, we are going to encounter an AttributeError and might’t set the attribute. The reason being that we have to use a setter to set an attribute if we now have used @property to get a property. Let’s create a setter, the syntax might look unusual at first sight:

Nonetheless, this time, we now have a RecursionError error. It’s because the quantity property will not be an everyday property anymore because of the decorations. Notice that we now have two quantity strategies with the identical identify. self.quantity is now a property object with a getter and setter, and never an occasion property with a string worth anymore.

To unravel this drawback, we have to use a distinct property identify for the “actual quantity” within the getter and setter. Let’s simply introduce an underscore prefix to make it non-public property and keep away from identify conflicts. Truly, the entire level of utilizing getter and setter is that the property of a category occasion shouldn’t be obtained and altered immediately, however finished with some logic. On this instance, within the getter, we format the quantity earlier than it’s returned. And within the setter, we verify if the quantity is a sound quantity earlier than it’s set as a property. Let’s see if it really works with this replace:

Hooray, it really works! Let’s attempt to set an invalid quantity to the cellphone and see what’s going to occur:

cellphone.quantity = "123"
# ValueError: Invalid telephone quantity.

Glorious, it really works as anticipated. Invalid numbers can be rejected.

In case you might be questioning why the syntax of the getter and setter is so bizarre, you possibly can attempt to perceive it by determining how decorator works. A decorator is a special function that returns a decorated function. On this instance, underneath the hood, the built-in property class is used. property is a category although it’s in decrease case. Fairly unusual, isn’t it. Nevertheless it’s not the strangest half. The primary argument of the property class is a getter. The getter perform can be triggered whenever you attempt to entry the property object created, for instance (cellphone.quantity).

Due to this fact, for the getter methodology, particularly the primary adorned quantity methodology on this instance, we are going to get one thing like:

quantity = property(quantity)
  • The quantity in parentheses is the quantity methodology being adorned (the getter perform).
  • The quantity on the left facet is a property object returned by the property class.

A property object has a setter methodology that may set the setter methodology for the property object. Due to this fact, for the setter perform, particularly the second adorned quantity methodology, you’ll get one thing like:

quantity = quantity.setter(quantity) 
  • The quantity on the correct facet is the setter methodology quantity being adorned.
  • The quantity within the center is the quantity (a property object) returned above, the one adorned with @propery.
  • The quantity on the left is the ultimate property object with each the getter and setter assigned.

It’s equal to the next kind:

quantity = property(quantity).setter(quantity)

See should you can work out what every quantity means.

The technical particulars of the @property decorator and the getter and setter are fairly advanced and are associated to the descriptor concept in Python. Don’t get pissed off, you don’t want to grasp all of the technical particulars of the @property decorator earlier than utilizing it. You possibly can simply use it as demonstrated within the Cellphone class. Quite simple syntax to make use of.

On this article, three magical decorators in Python, particularly @staticmethod, @classmethod, and @propery are launched with easy examples. Now you can begin to use it to optimize your code and make your code extra skilled.

The code is put collectively right here to your reference:

More Posts