Python Property – The Problem and Solution
Master Python with 70+ Hands-on Projects and Get Job-ready - Learn Python
In this tutorial on Python Property, you will learn how to use setters and getters using property.
Moreover, we will discuss the problems and solutions related to Python Property. Before we begin, take a look at Classes and Objects.
So, let’s start Python Property Tutorial.
What is Python Property?
Let’s first look at a Python class Song.
>>> class Song: def __init__(self,title): self.title=title def show_title(self): print(f"I'm listening to {self.title}")
We then create an object Teddy_Bear, and call show_title() on it.
>>> Teddy_Bear=Song('Teddy Bear') >>> Teddy_Bear.show_title()
Output
Here, we can get and set the title instance attribute this way:
>>> Teddy_Bear.title #getting the title
Output
>>> Teddy_Bear.title='TEDDY BEAR' #setting the title >>> Teddy_Bear.title
Output
Checking the object’s dictionary, we find this:
>>> Teddy_Bear.__dict__
Output
The problem: What if clients begin accessing and modifying the variable ‘title’? That could cause all kinds of chaos.
Python Property – A Possible Solution
Let’s do two things:
- Define setter and getter functions. To set and get a value, we define the following functions:
>>> def get_title(self): return self._title >>> def set_title(self,title): self._title=title.upper()
Here, get_title returns the title of the book, and set_title converts it to all caps (we saw this in
Python Built-in Functions)
- Make the variable ‘title’ private. To do this, we use a leading underscore. After all these changes, our class looks like this:
>>> class Song: def __init__(self,title): self.title=title def show_title(self): print(f"I'm listening to {self.title}") def get_title(self): return self._title def set_title(self,title): self._title=title.upper()
Well, the underscore doesn’t really make the variable private, because Python does not implement any such restriction at its level.
But these are the norms that we must follow.
But the problem with this solution is that we will need to update ‘Teddy_Bear.title’ to ‘Teddy_Bear.get_title()’ and ‘Teddy_Bear.title=’TEDDY BEAR’’ to ‘Teddy_Bear.set_title()’ in each occurrence.
Real-world code, clients may have thousands of lines where they implemented our class.
In that case, it becomes tedious to refactor every single occurrence. This makes it not backward-compatible.
So, let’s look at a better option next. Actually, we will just add a line to this approach, and it will work like magic.
Python Property – The Solution
To solve this problem, Python lends us the function property(). This is what this property of Python looks like:
property(fget, fset, fdel, doc)
Here, fget takes a getter, fset takes a setter, fdel takes a function to delete an attribute, and doc is a string.
These arguments, however, are optional. Here is a call to property() without any arguments:
>>> property()
Output
For fget, fset, and fdel, a property object has the following methods: getter(), setter(), and delete(). So, this is equivalent to this:
>>> title=property() #make empty property >>> title=title.getter(get_title) #assign fget >>> title=title.setter(set_title) #assign fset
For our class Song, we add the following line:
>>> title=property(get_title,set_title)
This makes the class look like this:
>>> class Song: def __init__(self,title): self.title=title def show_title(self): print(f"I'm listening to {self.title}") def get_title(self): return self._title def set_title(self,title): self._title=title.upper() title=property(get_title,set_title)
Now, let’s try accessing the title for the object Teddy_Bear.
>>> Teddy_Bear=Song('Teddy Bear') >>> Teddy_Bear.title
Output
>>> Teddy_Bear.show_title()
Output
This implementation is backward-compatible. This saves us from all the work of refactoring.
Also note that it is _title that holds the actual value of the book’s title. ‘title’ is just a property object that makes it happen.
Some Syntactic Sugar
We have seen the @-syntax in our lesson on Python Property Decorators. Here, we do this:
>>> class Song: def __init__(self,title): self.title=title def show_title(self): print(f"I'm listening to {self.title}") @property def title(self): return self._title @title.setter def title(self,title): self._title=title.upper()
Firstly, note that we removed the call to property. Next, we ditched the names ‘get_title’ and ‘set_title’, and used ‘title’ instead.
Finally, we used @property before the getter, and @title.setter before the setter.
Let’s access this now.
>>> Teddy_Bear=Song('Teddy Bear') >>> Teddy_Bear.title
Output
>>> Teddy_Bear.show_title()
Output
So, this was all about Python Property Tutorial. Hope you like our explanation.
Python Interview Questions on Property
- What is property in Python?
- What is the use of property in Python?
- What is Python class property?
- How does Python property work?
- What is the benefit of using property in Python?
Conclusion
In this tutorial on Python Property, we learned about different problem and solutions of this problems.
Did you like this article? If Yes, please give DataFlair 5 Stars on Google
Unfortunately, this example does not work. I ran it in Python 2.7.10 in PyDev.
class Song:
def __init__(self,title):
self.title=title
def show_title(self):
print(“I’m listening to %s” % (self.title))
@property
def title(self):
return self._title
@title.setter
def title(self,title):
self._title=title.upper()
Teddy_Bear=Song(‘Teddy Bear’)
print(Teddy_Bear.title)
Teddy_Bear.show_title()
Result:
Teddy Bear
I’m listening to Teddy Bear
Clearly, the setter does not work (no uppercase)
ok, this is python 3 syntax. For python 2, in order for properties to work properly, the class needs to inherit from object.
class Song(object)
It would be nice for the tutorial to indicate which version of python it is running
Hi Jen,
We are glad our audience is trying to connect with us. Yes, this syntax will work on Python 3. DataFlair is publishing tutorials on the latest versions of all technologies.
Keep exploring and keep learning from DataFlair
Well I did really say I’m very much with all your tutorials on Python.
I decided to comment here coz your code needed be updated
Teddy_Bear.title could still be accessed without using Teddy_Bear.get_title()
This is because the self.title in the __init__ is not yet updated to private.
Using this medium to say THANKX for such great tutorial
Hi Michael
Thanks for the comment on Python property. Here, we do mention in the text that it is still accessible without the get_title() method.
“Well, the underscore doesn’t really make the variable private, because Python does not implement any such restriction at its level. But these are the norms that we must follow.”
Hope, it will solve your query!
Regards DataFlair