peut pas définir de nouvel opérateur. Mais on peut tous les surcharger __add__, __sub__, __mul__, __div__, __pow__, __and__, __or__, ... __radd__, ... : paramètres échangés __iadd__, ... : +=, ...
peut pas définir de nouvel opérateur. Mais on peut tous les surcharger __add__, __sub__, __mul__, __div__, __pow__, __and__, __or__, ... __radd__, ... : paramètres échangés __iadd__, ... : +=, ... Exprimer naturellement des opérations sur n’importe quel type
nombreuses méthodes vers les types de base : __str__ __bool__ __int__ __long__ __float__ __complex__ __oct__ __hex__ __index__ Appelées par les fonctions str(), int(), ...
implémenter une séquence qui supporte toutes les opérations habituelles. Les méthodes à implémenter dépendent du type de la séquence : immutable → __len__ __getitem__ mutable → immutable + __setitem__ __delitem__ itérable → __iter__ bonus → __reversed__ __contains__ __missing__
__instancecheck__(self, instance) et __issubclass__(self, subclass) Permettent de redéfinir (une partie de) la résolution des parentés des classes Relativement moins utile pythonic : mieux vaut essayer de faire ce qu’on veut et échouer que tester de manière préventive
self.name n’existe pas __setattr__(self, name, value) à chaque assignement __delattr__(self, name) lors de del self.name __getattribute__(self, name) toujours appelé __dir__ lister les attributs
name, value): # implementation de base self.__dict__[name] = value # marche aussi super().__setattr__(name, value) # equivalent a self.__setattr__("name", value) # => boucle infinie self.name = value
def __priv(self, **kwargs): self.__private__.update(kwargs) def __getattribute__(self, name): if name in self.__public__: return self.__public__[name] elif self.__from_inside__() and name in self. __private__: return self.__private__[name] raise AttributeError(name) def __setattr__(self, name, value): if self.__from_inside__() and name in self. __private__: self.__private__ [name] = value else: self.__public__[name] = value
self.__from_inside__() and name in self. __private__: del self.__private__ [name] def __from_inside__(self): stack = inspect.stack() parent_locals = stack[2][0].f_locals return "self" in parent_locals and parent_locals ["self"].__class__ == self.__class__
c’est super pour Bien s’intégrer au langage Implémenter finement certains comportements Mettre les mains dans le fonctionnement internes des objets Merci pour votre attention ! Des questions ? Slides dispos sur https://speakerdeck.com/brunal/methodes-magiques