Skip to main content
Taught by Tech Leads

Master pipelines, cloud & AI to become an operational Data Engineer.

DataScientist.fr
Image de Enhance Your Python Classes with @property - Practical Tutorial
Python

Enhance Your Python Classes with @property - Practical Tutorial

Photo de Romain DE LA SOUCHÈRE

Tech Lead, CTO AXI Technologies

Published on 2 janvier 2025 · 10 min of reading

In the world of programming, effective management of class attributes is essential for creating robust and maintainable applications. Python, with its built-in property() functionality, offers an elegant approach to controlling access and modification of attributes. Whether you need read-only, read-write, or even write-only properties, understanding how and when to employ these techniques can transform your code into a work of software art. Let's dive into the world of Python properties and discover how to optimize attribute management in your classes.

Managing attributes in your classes

In software development, managing attributes in Python classes is an essential skill that can greatly enhance the flexibility and maintainability of your code. In this section, we will explore how Python allows for fine control over attribute management with built-in tools like properties and descriptors.

Using properties

Properties in Python allow you to define access and modification methods for a class's attributes without changing the access syntax. Using properties is an elegant way to control access to instance attributes while maintaining a simple user interface. Here is a basic example:
python
In this example, we used the decorator @property to create access methods width and height, while providing modification methods with @width.setter and @height.setter. This allows for controlling and validating values before assigning them to the attributes.

Descriptors for advanced control

Descriptors offer a more powerful way to manage attributes by providing a means to customize access and modification logic at a lower level. A descriptor is a class that implements at least one of the following methods: __get__, __set__, or __delete__.
python
With descriptors, we encapsulate the management of the width and height attributes within the PositiveValue class, allowing us to reuse this logic in other classes.

Advantages and limitations

Using properties and descriptors allows for finer control over attribute access, adding validations, logging, or other custom logic. However, it can also introduce additional complexity if each attribute requires unique management. It is crucial to find the right balance between simplicity and advanced functionality in your class designs.

Getting started with Python's property()

To get started with property() in Python, it is essential to understand how this built-in function allows you to transform class methods into attributes. This offers the possibility of managing access to private data while maintaining a clean and intuitive user interface.

Creating a basic property

The property() function allows you to define an access method (getter), a modification method (setter), and a deletion method (deleter) for an attribute. Here’s how to create a simple property:
python
In this example, name is defined as a property. get_name is used to access the private attribute _name, and set_name to modify it. This allows for controlling how the attributes are manipulated.

Using decorators for simplification

The decorators @property, @name.setter, and @name.deleter provide a more concise syntax for creating properties. Let’s see how to simplify the previous example with decorators:
python
With decorators, the code becomes more readable and easier to maintain, as each part of the property is clearly defined and accessible.

Why use property()?

Using property() is particularly beneficial when you want to:
  • Add validations: Before modifying an attribute, you can check its validity.
  • Control access: Limit direct access to sensitive data in your objects.
  • Maintain a clear API: Allow users of the class to access attributes as if they were public variables, while encapsulating complex logic.
By adopting property(), you can create robust and flexible Python classes while preserving the simplicity and readability of your code.

Deciding when to use properties

Deciding when to use properties in your Python classes depends on several factors related to the structure and needs of your application. Properties can enrich your code by adding controls and preserving business logic while maintaining an intuitive user interface.

Use cases for properties

Here are some situations where using properties is particularly advantageous:
  • Data validation: If an attribute must adhere to certain constraints, properties allow for incorporating validations directly into the setter method. For example, you can ensure that a value remains within a specific range, as seen with the dimensions of a rectangle.
  • Controlled access: For attributes requiring access control, such as sensitive information or computed data, properties provide a means to control reading and writing without exposing the underlying attributes directly.
  • On-demand calculations: When the value of an attribute depends on other attributes and needs to be dynamically recalculated, you can use properties to implement this logic without storing redundant data. For instance, calculating the area of a rectangle from its width and height.

When to avoid properties

Although properties are powerful, they are not always the ideal solution:
  • Simplicity and performance: If an attribute is simply a data container without specific logic, using properties may introduce unnecessary complexity. Properties also introduce a slight performance overhead, which can be relevant in contexts where every millisecond counts.
  • Compatibility and refactoring: If you need to ensure backward compatibility with existing code that accesses attributes directly, introducing properties may require significant adjustments.

Conclusion

In summary, the judicious use of properties can improve the quality of your code by adding additional levels of control while maintaining a simple user interface. Always assess the specific needs of your project to determine if properties are necessary or if direct access suffices.

Providing read-only attributes

In some cases, you might want to expose attributes as read-only to protect data integrity or to ensure that certain values can only be modified at specific times, such as during object initialization. Python simplifies the creation of these read-only attributes through the use of properties.

Creating a read-only property

To create a read-only attribute, you can define a property with only a getter method, without a corresponding setter method. This prevents any direct modification of the attribute from outside the class. Here’s how this is done:
python
In this example, number and balance are read-only attributes. Once a BankAccount object is created, its values cannot be modified directly.

Using the read-only attribute

Read-only attributes are particularly useful when a value must remain constant after its initial definition. For example, a bank account number should not be modified once assigned:
python

Advantages of read-only attributes

Using read-only attributes offers several advantages:
  • Data protection: Ensures that certain critical data is not inadvertently modified.
  • Encapsulation: Hides the logic of calculating or determining the value while exposing only the result of that logic.
  • Stability: Guarantees that certain information remains constant, which can be essential for system consistency.
By implementing read-only attributes, you can enhance the robustness and reliability of your classes by protecting important data and providing a clear and safe interface to your users.

Creating read-write attributes

Creating read-write attributes in a Python class is a common practice that allows for data manipulation while maintaining a certain level of control over access and modification. Using properties, you can easily manage these attributes with custom access and modification methods.

Defining read-write properties

To define a read-write attribute, you need to provide a getter method to access the attribute and a setter method to modify it. Here’s an example illustrating this approach:
python
In this example, brand and max_speed are read-write attributes, allowing the user to read and modify these values under certain conditions.

Managing validations and business logic

One of the main advantages of read-write properties is the ability to integrate validations and business logic directly into the setter methods. This ensures that each modification adheres to defined rules, as in the example where the brand must be a non-empty string and the maximum speed must be positive.

Using read-write attributes

Here’s how you can interact with read-write attributes:
python
This flexibility allows for maintaining control over the data while providing an intuitive and simple interface for users of your class. By correctly implementing read-write properties, you ensure effective management of your class attributes while preserving data integrity.

Providing write-only attributes

Providing write-only attributes is a less common but useful approach in certain situations where you want to allow users to set a value but not read it directly. This technique can be applied for security reasons or when the value of an attribute needs to be transformed or aggregated before being exposed.

Creating a write-only attribute

To create a write-only attribute, you must define a setter method without a corresponding getter method. This prevents direct access to the attribute's value while allowing it to be modified. Here’s an example:
python
In this example, the logs attribute is designed to be modified but not directly accessible. The setter adds messages to the log without providing a method to read each entry directly.

Usage in practice

Write-only attributes can be useful for logging sensitive information or for implementing actions triggered by the modification of an attribute:
python

Advantages and considerations

Using write-only attributes offers several advantages, including:
  • Enhanced security: Prevents access to sensitive or critical data. For instance, storing passwords as hashes without allowing direct reading of the plaintext password.
  • Encapsulation of actions: Allows for triggering actions or transformations whenever a value is assigned, without exposing the internal logic.
However, it is important to note that this approach should be used judiciously, as it may make the class less intuitive for users who expect to be able to read an attribute after setting it.
In summary, write-only attributes can be an effective solution for specific use cases, balancing security and functionality.

Putting Python's property() into practice

Putting Python's property() into practice allows you to fully leverage its capabilities for managing class attributes in a controlled and structured manner. In this section, we will see how to integrate the previous concepts into practical scenarios.

Example of managing a complex class

Suppose you are developing a library management application. You need a Book class to represent each book, with attributes such as title, author, and number of pages. Some of these attributes require thorough control. Here’s how to use property() to manage them:
python
In this example, title and pages are read-write attributes with validations, while author is read-only, ensuring that data integrity is maintained.

Integration and testing

To test this class, you can create instances of Book and try accessing and modifying its attributes:
python
This example demonstrates how property() can be used to enhance the security and reliability of your code by ensuring that attributes are always in a valid state. By integrating property() in this way, you can create robust and well-structured classes for your Python applications.

Conclusion

In conclusion, using property() in Python offers considerable flexibility for managing class attributes. By leveraging properties, you can not only control how attributes are read and modified but also encapsulate the necessary validation and calculation logic to protect data integrity.

Summary of benefits

Integrating property() allows you to:
  • Simplify the user interface: Users of your class can access attributes as if they were public, while benefiting from the protection and validation you have implemented.
  • Add validations: Ensure that your class attributes meet certain conditions every time they are modified.
  • Encapsulate business logic: Keep the logic for calculation or transformation internal without exposing the details of that logic.
By applying these concepts, you can design Python classes that are not only flexible and accessible but also robust and secure. Whether for ensuring read-only, read-write, or even write-only attributes, using property() provides you with the necessary tools to effectively meet the specific needs of your application. Adopt this approach to enrich your projects and improve the overall quality of your code.

Want to go further?

This topic is part of our Become a Data Analyst course. Browse the full programme, or get it by email.

Share with

Photo de Romain DE LA SOUCHÈRE

Romain DE LA SOUCHÈRE

Tech Lead, CTO AXI Technologies

Expert Data Engineering et Cloud, Romain affiche plus de 11 ans d'expérience, dont plusieurs années comme Lead Developer sur des solutions Smart Building haute performance. Il y a conçu et mis en production des moteurs de traitement capables d'absorber des centaines de milliers de données de capteurs par minute, ainsi que des bases clusterisées gérant plus de 10 millions de données dynamiques. Certifié Microsoft Azure DevOps Engineer Expert, il maîtrise aussi bien le développement back-end (Python, C#) que le DevOps (Docker, Kubernetes, Terraform) et les agents LLM. Formateur en Python, cloud, DevOps et IA générative appliquée, il forme avec une obsession : Amener chaque apprenant à concevoir et déployer des architectures réellement scalables en production.

» Learn More

Associated trainings

All our trainings
Image de la formation Become a Data Analyst
Become a Data Analyst
6 months
Intermediate
Guarantee

Associated articles

See all our articles