Python: Decorators in OOP
By: Aniruddha Karajgi
Tags: Python, Java, Object Oriented, Programming

The getter and setter methods

Let’s start with getter and setter methods. These methods are used to access and modify (respectively) a private instance. In Java, we would do something like this:

Now, anytime you access or modify this value, you would use these methods. Since the variable x is private, it can’t be accessed outside JavaClass .

In python, there is no private keyword. We prepend a variable by a dunder( __ ) to show that it is private and shouldn’t be accessed or modified directly.

Adding a __ before a variable name modifies that variable’s name from varname to _Classname__varname , so direct access and modification like print(obj.varname) and obj.varname = 5 won’t work. Still, this isn’t very strong since you could directly replace varname with the modified form to get a direct modification to work.

Let’s take the following example to understand this:

Adding getter and setter methods

Taking our Student class example, let’s make the score attribute “private” by adding a __ before the variable name.

If we directly went ahead and added get_score and set_score like Java, the main issue is that if we wanted to do this to existing code, we’d have to change every access from:

print("Score: " + str(student1.score))

student1.score = 100

to this:

print(student1.get_score())

student1.set_score(100)

Here’s where the @property decorator comes in. You can simply define getter , setter and deleter methods using this feature.

Our class now looks like this:

To make the attribute score read-only, just remove the setter method.

Then, when we update score , we get the following error:

Traceback (most recent call last):

File "main.py", line 16, in <module>

student.score = 10

AttributeError: can't set attribute

The deleter method

The deleter method lets you delete a protected or private attribute using the del function. Using the same example as before, if we directly try and delete the score attribute, we get the following error:

student = Student("Tom", 50, 100)

del student.score This gives:

Traceback (most recent call last):

File "<string>", line 17, in <module>

AttributeError: can't delete attribute

But when we add a deleter method, we can delete our private variable score .

The attribute has been successfully removed now. Printing out the value of score gives “object has no attribute…”, since we deleted it.

Traceback (most recent call last):

File "<string>", line 23, in <module>

File "<string>", line 9, in x

AttributeError: 'PythonClass' object has no attribute '__score'

use-cases for the property decorator

The property decorator is very useful when defining methods for data validation, like when deciding if a value to be assigned is valid and won’t lead to issues later in the code.

Another use-case would be when wanting to display information in a specific way. Coming back to our example, if we wanted to display a student’s name as “Student Name: <name>” , instead of just <name> , we could return the first string from a property getter on the name attribute:

Now, any time we access name , we get a formatted result.

student = Student("Bob", 350, 500)

print(student.name)

The output:

Student Name: Bob

The property decorator can also be used for logging changes.

For example, in a setter method, you could add code to log the updating of a variable.

Now, whenever the setter is called, which is when the variable is modified, the change is logged. Let’s say there was a totaling error in Bob’s math exam and he ends up getting 50 more marks.

student = Student("Bob", 350, 500)

print(student.score)

student.score = 400

print(student.score)

The above gives the following output, with the logged change visible:

70.0 %

INFO:root:Setting new value...

80.0 %

Finally, our class looks like this: