Personnaliser l'accès aux attributs

Programmation orientée objet intermédiaire en Python

Jake Roach

Data Engineer

AttributeError

class Student:
  def __init__(self, student_name, major):
    self.student_name = student_name
    self.major = major
...
karina = Student("Karina", "Literature")
student.residence_hall  # Tentative d'accéder à un attribut qui n'existe pas
...
AttributeError: 'Student' object has no attribute 'residence_hall'
Programmation orientée objet intermédiaire en Python

__getattr__()

# Le reste de la classe ci-dessus

  def __getattr__(self, name):
    # Logique à implémenter ici
    ...

L'espace de noms d'un objet est l'ensemble des attributs qui lui sont associés

__getattr__() s'exécute lorsqu'on tente d'accéder à n'importe quel attribut qui est absent de l'espace de noms de l'objet

  • Méthode magique, non appelée directement
  • Prend un paramètre name
  • Permet une logique personnalisée au lieu de lever un AttributeError
Programmation orientée objet intermédiaire en Python

Résoudre l'AttributeError

class Student:
  def __init__(self, student_name, major):
    self.student_name = student_name
    self.major = major

  def __getattr__(self, name):
      print(f"""{name} does not exist in this object's namespace, try setting 
            a value for {name} first""")
karina.residence_hall  # Maintenant, réessayez de récupérer l'attribut residence_hall
residence_hall does not exist in this object's namespace, try setting a value for 
  residence_hall first
Programmation orientée objet intermédiaire en Python

__setattr__()

__setattr__() est une méthode magique exécutée lorsqu'un attribut (nouveau ou existant) est défini ou mis à jour

  • Comprend les attributs définis via __init__()
  • Prend le name de l'attribut et sa value
  • S'appuie sur l'attribut __dict__ de l'objet

$$

$$

Contrôler les modifications d'attributs, valider, transformer

# Le reste de la classe ci-dessus

  def __setattr__(self, name, value):
    # Logique à implémenter ici
    ...

    # Utiliser __dict__ pour créer/mettra à jour 
    # l'attribut
    self.__dict__[name] = value

__dict__ stocke tous les attributs de l'objet ; peut servir à lire et écrire des données

Programmation orientée objet intermédiaire en Python

Personnaliser le stockage des attributs

class Student:
  def __init__(self, student_name, major):
    self.student_name = student_name
    self.major = major

  def __setattr__(self, name, value):
    # Si la valeur est une chaîne, définir l'attribut via __dict__
    if isinstance(value, str):
      print(f"Setting {name} = {value}")
      self.__dict__[name] = value

    else: # Sinon, lever une exception pour un type de données incorrect
        raise Exception("Unexpected data type!")
Programmation orientée objet intermédiaire en Python

__setattr__ en action

# Définir un attribut avec une valeur de type 'str'
karina.residence_hall = "Honors College South"
print(karina.residence_hall)
Setting residence_hall = Honors College South
Honors College South
# Définir un attribut avec une valeur de type 'int'
karina.student_id = 19301872
...
    raise Exception("Unexpected data type!")
Exception: Unexpected data type!
Programmation orientée objet intermédiaire en Python

Utiliser __getattr__ et __setattr__ ensemble

class Student:
    ...   

    def __getattr__(self, name):
        # Définir l'attribut avec une valeur de remplacement
        self.__setattr__(name, None)
        return None

    def __setattr__(self, name, value):
        if value is None:  # Afficher un message indiquant une valeur de remplacement
            print(f"Setting placeholder for {name}")

        self.__dict__[name] = value  # Définir l'attribut
Programmation orientée objet intermédiaire en Python

Passons à la pratique !

Programmation orientée objet intermédiaire en Python

Preparing Video For Download...