web-dev-qa-db-fra.com

Comment remplacer correctement __setattr__ et __getattribute__ sur les classes de nouveau style en Python?

Je veux remplacer mon Python classe _ __getattribute__ et __setattr__ méthodes. Mon cas d'utilisation est celui habituel: j'ai quelques noms spéciaux que je veux gérer, et je veux le comportement par défaut pour tout le reste. Pour __getattribute__, il semble que je puisse demander le comportement par défaut simplement en augmentant AttributeError. Cependant, comment puis-je obtenir la même chose dans __setattr__? Voici un exemple trivial, implémentant une classe avec des champs immuables "A", "B" et "C".

class ABCImmutable(SomeSuperclass):
    def __getattribute__(self, name):
        if name in ("A", "B", "C"):
            return "Immutable value of %s" % name
        else:
            # This should trigger the default behavior for any other
            # attribute name.
            raise AttributeError()

    def __setattr__(self, name, value):
        if name in ("A", "B", "C"):
            raise AttributeError("%s is an immutable attribute.")
        else:
            # How do I request the default behavior?
            ???

Qu'est-ce qui remplace les points d'interrogation? Avec les classes à l'ancienne, la réponse était apparemment self.__dict__[name] = value, mais la documentation indique que cela est incorrect pour les classes de nouveau style.

41
Ryan C. Thompson

Ses

super(ABCImmutable, self).__setattr__(name, value)

dans Python 2, ou

super().__setattr__(name, value)

dans Python 3.

En outre, augmenter AttributeError n'est pas pas la façon dont vous revenez au comportement par défaut pour __getattribute__. Vous revenez à la valeur par défaut avec

return super(ABCImmutable, self).__getattribute__(name)

sur Python 2 ou

return super().__getattribute__(name)

sur Python 3.

Augmenter AttributeError ignore la gestion par défaut et passe à __getattr__, ou produit simplement un AttributeError dans le code appelant s'il n'y a pas __getattr__.

Voir la documentation sur Personnalisation de l'accès aux attributs .

45
Hank Gay

SomeSuperclass.__setattr__(self, name, value) ?

6
Jeannot