Alors voilà, je me posais des questions sur l'overriding des types primitifs. N'étant pas un expert, un problème s'est posé à moi :
_list=list
class List(_list):
# Simple surcharge de l'initiateur
def __init__(self,**kwargs):
print('ayaaa')
_list.__init__(self,**kwargs)
list=List
Je souhaite donc être informé lorsque __init__ est appelé. Sauf que en faisant :
l = list()
'ayaaa' est en effet affiché, niquel, mais pour :
l = []
Rien ne sort...
Je cherche simplement à comprendre, ou du moins être redirigé vers de la littérature à ce sujet...
Second problème, je n'ai pas trouvé de meilleur moyens pour overrider la méthode d'une classe existante (sans en créer de nouvelle), que ce que j'ai fais ci-dessus, à savoir passer par _list
Ca me semble une terrible idée ce que tu essayes de faire, si déjà c'est seulement possible. Pourquoi vouloir écraser le type primitif existant ? En python pur, je doute que tu puisses modifier l'interprétation des brackets, à vérifier cependant. Mais dans tous les cas, que ce soit dans ton premier exemple ou pour ton second problème, ce n'est pas quelque chose à faire.
Eeeeeeeeh merci Jevanni mais du coup ça répond assez mal à ma question
Pour ces histoires de parenthèses, crochets et autres accolades c'est simplement une remarque que je me fais, je trouve ça intéressant de comprendre perso...
EDIT :
Et pour ma seconde question je m'explique :
class Myclass:
def __init__(self,**kwargs):
pass
def meth(self):
pass
Et là, dans un autre fichier, je veux garder ma même classe mais en changeant le comportement de 'meth'. Y a-t-il une manière conventionnelle de faire ? Voilà.
Et de toute façon, la déontologie du développeur face aux langages qu'il utilise, bon... Si j'ai envie de redéfinir mes built-in je fais encore ce que je veux
MrFoxtrot a écrit:
> 'ayaaa' est en effet affiché, niquel, mais pour :
>
1
l = []
> Rien ne sort...
Rien de plus normal, tu n'as fait que rebinder le nom list sur une nouvelle classe, mais tu n'as pas remplacé la classe de base, celle qui est appelée quand une liste est instanciée.
Et tu ne peux pas faire cela à moins de modifier l'interpréteur.
Pour modifier une classe existante, tu peux utiliser du monkey-patching pour associer de nouveaux attributs/méthodes (Cls.method = new_method). Mais c'est impossible sur les types builtins.
Mais ça n'est jamais une bonne idée (donc pas pythonique).
A vérifier mais oui, je pense qu'il faudrait au moins rentrer dans du cynthon pour y accéder, et encore, je ne suis même pas sûr ... Après effectivement tu peux faire tout ce que tu veux, modifier l'interpréteur par exemple, mais ça reste une très mauvaise pratique. Pour redéfinir une méthode, pourquoi ne pas faire simplement de l'héritage ?
MrFoxtrot a écrit:
> Yes ok... donc le véritable instancieur des built-in est trop bas niveau pour que l'on puisse y avoir accès ?
Tu peux y accéder. L'instancieur d'une liste, c'est list donc list.__call__ qui crée l'objet avec list.__new__ et l'initialise avec list.__init__.
C'est juste que l'objet list est immutable (list en tant qu'objet, pas ses instances), donc tu ne peux pas modifier l'une de ses méthodes.
Pour le faire il faudrait passer outre les sécurités mises en place par l'interpréteur, et donc que le code soit exécuté au même niveau que l'interpréteur.
Ça se fait peut-être aussi à coups de bidouilles de ctypes, mais c'est très très sale.
Du Zen de Python : Explicit is better than implicit. Donc si tu as besoin de te faire une liste avec un comportement légèrement différent, tu crées une nouvelle classe qui n'hérite pas de list mais de UserList. Ensuite, tu instancies des objets de ta classe de manière explicite, donc pas avec des crochets ni en essayant de faire passer ta classe pour list.
Bon, je vous aime tous très fort, mais là jm'en carre de faire une liste qui affiche ayaaa à l'iniation hein, je voulais juste savoir deux ptits trucs, pour la science :D
Ceci dit je mes le topic en resolu mais continuez a m'enseigner
- Edité par MrFoxtrot 20 mars 2018 à 18:51:59
Quand est appelé l'initiateur des types built-in ?
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique