We know everyone hates setting property fields in Python classes, here’s how you can create getter setter properties in python classes to do it for you. In this article, you’ll see how to create these above properties.
Basically, maintaining data encapsulation is the key objective of using getters and setters in object-oriented programs. However, getters and setters are not the same in Python as those in other programming languages that are object-oriented. Private variables in python are not hidden fields, but then the idea of encapsulation is simulated in ways.
Python encapsulation is the concept of packaging together variables and methods into a single object. A class is an illustration of programming that encapsulates all the variables and methods specified inside it.
Consider the volume control of your radio. You don’t update the volume setting directly on the circuit board in order to change the volume. You instead use the volume control to adjust the settings, and the internal values are updated on the circuit board chip. Here the setter and getter is the volume control that helps you set a new value, and you get to see the current volume on the dial on the display.
If fields are not hidden, why use Python’s Getters and Setters ?
Even though you don’t get the strict control and privacy from attributes compared to other languages (e.g. Java has the concept of ‘private’ variables) it is still very useful to use getters and setters. Some key reasons include:
- To add validation logic around getting and setting a value
- In order to prevent direct access to a class field where internal function requires some control
- To provide some flexibility where the internal function can change without affecting how the class is accessed
How to Create Getter and Setter Properties in Python
There are several methods to create getter and setter functions:
- Method 1: By using a normal function to achieve the actions of getters and setters.
- Method 2: By using the property() function to implement the behaviour of getters and setters.
- Method 3: By using @property decorators to accomplish the actions of getters and setters (see our other article on how decorators work).
Method 1: By using a function
If we define basic get() and set() methods to achieve the property of getters & setters, it is easy to follow but will require some discipline to be consistent. For example:
#A python programme that displays a use of the methods get() and set() #in normal function class AgeSet: def __init__(self, age = 0): self._age = age # getter method def get_age(self): return self._age # setter method def set_age(self, x): self._age = x pkj = AgeSet() # setting the age using setter pkj.set_age(int(input("set the age using setter: "))) # retrieving age using getter print(pkj.get_age()) print(pkj._age)
According to the above code functions get_age() and set_age() functions as standard functions. You can also see that the private variable in the class was self._age. However, you can still access that without restriction. The underscore _ prefix is used as a convention to denote private variables but there is no restrictions, it is just a common practice.
Method 2: By using the property() function
The property() is a built-in function in Python that creates a property object and returns it. There are three methods for a property object, getter(), setter(), and delete (). The property() function has four arguments in Python: property(fget, fset, fdel, doc).
- fget is an attribute value retrieval function.
- fset is a function for setting a value for an attribute.
- fdel is an attribute value removal function.
- doc generates an attribute docstring.
The object property has three methods, getter(), setter(), and delete() to explicitly state fget, fset, and fdel.
# Python program displaying a use of the property() function class AgeSet: def __init__(self): self._age = 0 # function to get value of _age def get_age(self): print("getter method called") return self._age # function to set value of _age def set_age(self, a): print("setter method called") self._age = a # function to delete _age attribute def del_age(self): del self._age age = property(get_age, set_age, del_age) pkj = AgeSet() pkj.age = int(input("set the age using setter: ")) print(pkj.age)
There is only one print expression in the above code at line 25, but the output consists of three lines because of the setter method set_age() called in the input line, and getter method get_age() called in the print line. Therefore, age is a property object that helps to keep private variable access secure. As can be seen, within the class the property() function does the magic of assigning the getter and setter function.
Method 3: By using @property decorators
This is by far the easiest and the way that I recommend. In the previous step, we used the property() function to accomplish the action of getters and setters. However, as stated previously in this article, getters and setters are often used to validate the validity of attributes obtained and set. There is one more way to use the decorator to enforce the property function. One of the built-in decorators is python @property.
# Python program displaying the use of @property class AgeSet: def __init__(self): self._age = 0 # using property decorator a getter function @property def age(self): print("getter method called") return self._age # a setter function @age.setter def age(self, a): if(a < 18): raise ValueError("Sorry your age is below eligibility criteria") print("setter method called") self._age = a pkj = AgeSet() pkj.age = int(input("set the age using setter: ")) print(pkj.age)
In the above, it is clear how to use @property decorator in our python programming language to build getters & setters. You simply use the @property decorator to define the getter, and then use the @<variable>.setter to define the setter immediately above the relevant function. That’s it.
This is terrific, isn’t it? You can start with the easiest implementation imaginable, and without modifying the user interface, you are free to move to a property version later! So properties are not just a substitution for setters and getters!
Something else you may already have noticed: properties are syntactically similar to ordinary attributes for users of a class.
It is a common misconception that by using getters and setters, a proper Python class can encapsulate private attributes. As soon as a new attribute is added by one of these programmers, he or she will make it a private variable and create a getter and a setter “automatically” for these attributes. These programmers can even use an editor or an IDE, which automatically generates all private attributes with getters and setters. These tools also warn the programmer if a public attribute is used by her or him! When they read the following, Java programmers can wrinkle their brows, screw up their noses, or even yell in horror: The Pythonic way of adding attributes is to make them public.
Thanks for reading the full article, check out our other already uploaded articles if that comes to your intuitive attention.