Python Property – The Problem and Solution

1. Python Property

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.

Python property

Python Property

2. Python Property – The Problem

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()

I’m listening to Teddy Bear
Here, we can get and set the title instance attribute this way:

>>> Teddy_Bear.title #getting the title

‘Teddy Bear’

>>> Teddy_Bear.title='TEDDY BEAR' #setting the title
>>> Teddy_Bear.title

‘TEDDY BEAR’
Checking the object’s dictionary, we find this:

>>> Teddy_Bear.__dict__

{‘title’: ‘TEDDY BEAR’}
The problem: What if clients begin accessing and modifying the variable ‘title’? That could cause all kinds of chaos.

3. 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.

4. 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()

<property object at 0x062CDDB0>

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

‘TEDDY BEAR’

>>> Teddy_Bear.show_title()

I’m listening to TEDDY BEAR

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.

Python Interview Questions

5. 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

‘TEDDY BEAR’

>>> Teddy_Bear.show_title()

I’m listening to TEDDY BEAR

So, this was all about Python Property Tutorial. Hope you like ou explanation.

6. Conclusion

In this tutorial on Python Property, we learned about different problem and solutions of this problems. Comment a doubt or leave a suggestion. We surely get back to you!

For reference

5 Responses

  1. Jen says:

    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)

  2. Jen says:

    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

    • DataFlair Team says:

      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

  3. Micheal BlackGeek says:

    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

    • DataFlair Team says:

      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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.