Comment remplacer correctement setattr et getattribute sur les classes de style nouveau en Python?
Je veux remplacer les méthodes __getattribute__
et __setattr__
de ma classe Python. Mon cas d'utilisation est l'habitude: j'ai quelques noms que j'ai à gérer, et je veux le comportement par défaut pour autre chose. 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 l'ancien style classes, la réponse était apparemment self.__dict__[name] = value
, mais la documentation indique que c'est faux pour les classes de style nouveau.
2 réponses
C'est
super(ABCImmutable, self).__setattr__(name, value)
En Python 2, ou
super().__setattr__(name, value)
En Python 3.
En outre, élever AttributeError
est Pas comment 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.
Lever AttributeError
ignore la gestion par défaut et va à __getattr__
, ou produit simplement un AttributeError
dans le code appelant s'il n'y a pas de __getattr__
.
Voir la documentation sur l'attribut de personnalisation Accès .