Programmation Orientée Objet en Python
  • Back to Main Website
  • Home
  • Introduction: Histoire et Concepts
    • Introduction: Histoire et Concepts
    • Histoire de la programmation
    • Première Structuration des données
    • Naissance de la POO
    • Python: tout n’est qu’objet
    • Python : Simplicité des objets et performance sous-jacente
    • Classes en Python : Concepts fondamentaux

    • Travaux Pratiques
    • Construire sa propre Liste
    • Construire son propre DataFrame
  • Encapsulation, Héritage, Composition et Dunder
    • Encapsulation, Heritage, Composition et Dunder
    • Encapsulation en Python
    • Héritage en Python : Concept et intérêt
    • Héritage vs Composition
    • Méthodes Dunder en Python
    • Python call Method: A Fun Exploration

    • Travaux Pratiques
    • TP: Heritage avec le pricing d’option
    • TP : Ajouter des méthodes dunder à DataFrameSimple
    • TP : Étendre la classe Liste avec des méthodes dunder
    • TP: Dunder Method with Tensor for Automatic Differentiation
  • Polymorphisme et Surcharge
    • Polymorphisme et Surcharge
    • Polymorphism in Object-Oriented Programming
    • Polymorphism in Python: Function Overloading and Type Checking
    • Class Creation: Standard vs type()
    • Type Hinting, Typing Module, and Linters in Python
    • Abstract Classes
    • Protocol Classes

    • Travaux Pratiques
    • TP
  • Decorators
    • Design Patterns
    • The decorator pattern
    • Decorator Practically
    • Built-in Decorators and Standard Library Decorators in Python
    • Practical Decorators in Python Libraries

    • Travaux Pratiques
    • TP: Monte Carlo Option Pricing with Decorators
    • TP: Optimizing Heston Model Monte Carlo Simulation
  • Project Management and Packaging
    • Project and Package
    • Organizing Python Projects
    • Understanding imports
    • Python Package Management and Virtual Environments
    • Unit Testing in Python

    • Travaux Pratiques
    • TP: Creating a Linear Regression Package
  • Design Patterns
    • OOP Design Patterns
    • Python-Specific Design Patterns
    • Creation Design Patterns
    • Structural Design Patterns
    • Behavioral Design Pattern

    • Travaux Pratiques
    • TP
  • Sujets de Projets possibles
    • Projets
    • Projets POO - 2024-2025
  • Code source
  1. Python-Specific Design Patterns
  • OOP Design Patterns
  • Python-Specific Design Patterns
  • Creation Design Patterns
  • Structural Design Patterns
  • Behavioral Design Pattern
  • Travaux Pratiques
    • TP

On this page

  • Python-Specific Design Patterns
    • 5.1 Context Managers
      • The with Statement
      • Implementing Custom Context Managers
      • Using contextlib
      • Async Context Managers
    • 5.2 Descriptors
      • Meaningful Descriptor Example
      • Advanced Descriptor: Lazy Property

Python-Specific Design Patterns

Cours
Fondamentaux
Learn about Python-specific design patterns, including context managers and descriptors, to write more efficient and Pythonic code.
Author

Remi Genet

Published

2024-10-21

Python-Specific Design Patterns


5.1 Context Managers

Context managers in Python provide a clean way to manage resources, ensuring proper acquisition and release.

The with Statement

Implementing Custom Context Managers

Explanation of __exit__ parameters: - exc_type: The type of the exception that occurred, or None if no exception occurred. - exc_value: The exception instance, or None if no exception occurred. - traceback: A traceback object, or None if no exception occurred.

Using contextlib

Async Context Managers

5.2 Descriptors

Descriptors provide a way to customize attribute access in Python classes.

Meaningful Descriptor Example

Explanation of __get__ parameters: - obj: The instance that the attribute was accessed through, or None when the attribute is accessed through the class. - objtype: The class that was used to access the attribute. This is set even when called on an instance.

The difference between __get__ and getattr: - __get__ is a method of the descriptor object itself. It’s called when accessing an attribute that is a descriptor. - getattr is a built-in function that retrieves an attribute from an object. Inside __get__, we often use getattr to access the actual stored value.

Advanced Descriptor: Lazy Property

Now, let’s break down how this works step by step:

  1. When @LazyProperty is applied to the data method in DataProcessor:
    • An instance of LazyProperty is created, with the data method as its function attribute.
    • This LazyProperty instance replaces the data method in the class dictionary.
  2. When we create a DataProcessor instance:
    • No data is loaded yet. The filename is stored, but data is not accessed.
  3. The first time processor.data is accessed:
    • Python sees that data is a descriptor (it has a __get__ method) and calls LazyProperty.__get__(processor, DataProcessor).
    • Inside __get__:
      1. It checks if obj (processor) is None. It’s not, so it continues.
      2. It calls self.function(obj), which is equivalent to calling the original data method.
      3. This prints “Loading data…” and reads the file.
      4. The result is stored back into the processor instance using setattr(obj, self.name, value).
      5. The value is returned.
  4. The second time processor.data is accessed:
    • Python first looks for an instance attribute named data.
    • It finds one (because we set it in step 3d), so it returns that value directly.
    • The LazyProperty.__get__ method is not called this time.

The key point is that after the first access, the LazyProperty descriptor is effectively replaced by the computed value. This is why the “Loading data…” message only appears once.

These examples demonstrate how context managers and descriptors can be used to create more robust, efficient, and Pythonic code. Context managers excel at resource management, while descriptors offer powerful ways to customize attribute behavior.

Back to top
OOP Design Patterns
Creation Design Patterns

Programmation Orienté Object en Python, Rémi Genet.
Licence
Code source disponible sur Github

 

Site construit avec et Quarto
Inspiration pour la mise en forme du site ici
Code source disponible sur GitHub