Python Language Conversions bidirectionnelles


Exemple

Les objets descripteurs peuvent permettre aux attributs d'objet associés de réagir automatiquement aux modifications.

Supposons que nous voulions modéliser un oscillateur avec une fréquence donnée (en Hertz) et une période (en secondes). Lorsque nous mettons à jour la fréquence à laquelle nous souhaitons mettre à jour la période et que nous mettons à jour la période, nous voulons que la fréquence soit mise à jour:

 >>> oscillator = Oscillator(freq=100.0)  # Set frequency to 100.0 Hz
>>> oscillator.period  # Period is 1 / frequency, i.e. 0.01 seconds
0.01
>>> oscillator.period = 0.02  # Set period to 0.02 seconds
>>> oscillator.freq # The frequency is automatically adjusted
50.0
>>> oscillator.freq = 200.0  # Set the frequency to 200.0 Hz
>>> oscillator.period  # The period is automatically adjusted
0.005

Nous sélectionnons l'une des valeurs (fréquence, en Hertz) comme "ancre", c'est-à-dire celle qui peut être définie sans conversion, et écrivons une classe de descripteur pour cela:

class Hertz(object):
    def __get__(self, instance, owner):
        return self.value

    def __set__(self, instance, value):
        self.value = float(value)

La valeur "autre" (point, en secondes) est définie en fonction de l'ancre. Nous écrivons une classe de descripteur qui effectue nos conversions:

class Second(object):
    def __get__(self, instance, owner):
        # When reading period, convert from frequency
        return 1 / instance.freq
    
    def __set__(self, instance, value):
        # When setting period, update the frequency
        instance.freq = 1 / float(value)

Nous pouvons maintenant écrire la classe Oscillator:

class Oscillator(object):
    period = Second()  # Set the other value as a class attribute

    def __init__(self, freq):
        self.freq = Hertz()  # Set the anchor value as an instance attribute
        self.freq = freq  # Assign the passed value - self.period will be adjusted