Python Property

Summary: in this tutorial, you’ll learn about the Python property class and how to use it to define properties for a class.

Introduction to class properties #

The following defines a Person class that has two attributes name and age, and create a new instance of the Person class:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


john = Person('John', 18)Code language: Python (python)

Since age is the instance attribute of the Person class, you can assign it a new value like this:

john.age = 19Code language: Python (python)

The following assignment is also technically valid:

john.age = -1Code language: Python (python)

However, the age is semantically incorrect.

To ensure that the age is not zero or negative, you use the if statement to add a check as follows:

age = -1
if age <= 0:
    raise ValueError('The age must be positive')
else:
    john.age = ageCode language: Python (python)

And you need to do this every time you want to assign a value to the age attribute. This is repetitive and difficult to maintain.

To avoid this repetition, you can define a pair of methods called getter and setter.

Getter and setter #

The getter and setter methods provide an interface for accessing an instance attribute:

  • The getter returns the value of an attribute
  • The setter sets a new value for an attribute

In our example, you can make the age attribute private (by convention) and define a getter and a setter to manipulate the age attribute.

The following shows the new Person class with a getter and setter for the age attribute:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.set_age(age)

    def set_age(self, age):
        if age <= 0:
            raise ValueError('The age must be positive')
        self._age = age

    def get_age(self):
        return self._ageCode language: Python (python)

How it works.

In the Person class, the set_age() is the setter and the get_age() is the getter. By convention the getter and setter have the following name: get_<attribute>() and set_<attribute>().

In the set_age() method, we raise a ValueError if the age is less than or equal to zero. Otherwise, we assign the age argument to the _age attribute:

def set_age(self, age):
    if age <= 0:
        raise ValueError('The age must be positive')
    self._age = ageCode language: Python (python)

The get_age() method returns the value of the _age attribute:

def get_age(self):
    return self._ageCode language: Python (python)

In the __init__() method, we call the set_age() setter method to initialize the _age attribute:

def __init__(self, name, age):
    self.name = name
    self.set_age(age)Code language: Python (python)

The following attempts to assign an invalid value to the age attribute:

john = Person('John', 18)
john.set_age(-19)Code language: Python (python)

And Python issued a ValueError as expected.

ValueError: The age must be positiveCode language: Python (python)

This code works just fine. But it has a backward compatibility issue.

Suppose you released the Person class for a while and other developers have been already using it. And now you add the getter and setter, all the code that uses the Person won’t work anymore.

To define a getter and setter method while achieving backward compatibility, you can use the property() class.

The Python property class #

The property class returns a property object. The property() class has the following syntax:

property(fget=None, fset=None, fdel=None, doc=None)Code language: Python (python)

The property() has the following parameters:

  • fget is a function to get the value of the attribute, or the getter method.
  • fset is a function to set the value of the attribute, or the setter method.
  • fdel is a function to delete the attribute.
  • doc is a docstring i.e., a comment.

The following uses the property() function to define the age property for the Person class.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def set_age(self, age):
        if age <= 0:
            raise ValueError('The age must be positive')
        self._age = age

    def get_age(self):
        return self._age

    age = property(fget=get_age, fset=set_age)Code language: Python (python)

In the Person class, we create a new property object by calling the property() and assign the property object to the age attribute. Note that the age is a