class InstState:                           # Wykorzystanie stanu instancji
    def __get__(self, instance, owner):
        print('pobranie InstState')             # Założenie ustawienia przez klasę klienta
        return instance._X * 10

    def __set__(self, instance, value):
        print('ustawienie InstState')
        instance._X = value

# Klasa klienta
class CalcAttrs:
    X = InstState()                        #Atrybut deskryptora klasy
    Y = 3                                  # Atrybut deskryptora klasy
    def __init__(self):
        self._X = 2                        # Atrybut instancji
        self.Z  = 4                        # Atrybut instancji

obj = CalcAttrs()
print(obj.X, obj.Y, obj.Z)                 # X jest obliczane, reszta nie
obj.X = 5                                  # Przypisanie X jest przechwytywane
CalcAttrs.Y = 6                            # Wartość przypisana ponownie atrybutowi Y w klasie
obj.Z = 7                                  # Wartość przypisana atrybutowi Z w instancji
print(obj.X, obj.Y, obj.Z)

obj2 = CalcAttrs()                         # Tym razem wartość X jest inna, podobnie jak Z!
print(obj2.X, obj2.Y, obj2.Z)

