IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Classe dérivée de 'list' avec un membre en plus.


Sujet :

Python

  1. #1
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut Classe dérivée de 'list' avec un membre en plus.
    Bonjour,

    je souhaite créer un classe qui hérite de la classe "list" mais qui en plus soit capable de me donner le nombre max d'éléments qu'elle a contenu.

    Si j'écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class my_list ( list ):
       def __init__ (self):
          self.max_len = 0
    Il me dit (avec raison) que 'list' n'a pas d'attribut 'max_len'.

    max_len doit bien sûr contenir le nb max d'éléments (i.e. à chaque accroissement de la liste,
    il faut le mettre à jour avec un truc du genre max_len = max( max_len,len( self ))

    Si j'agrège (au lieu de dériver)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class my_list :
       def __init__ (self):
          self.the_list = []
          self.max_len = 0
    Il me faudra réécrire toutes les méthodes de 'list' !

    Y a-t-il un moyen de faire ce que je veux ?

    Merci d'avance !

  2. #2
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Salut

    Toujours appeler le constructeur de la classe parent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> class MyList(list):
    ...     def __init__(self):
    ...         list.__init__(self)
    ...         self.maxLen = 0
    ... 
    >>> l = MyList()
    Edit: Si tu travailles avec Python 2.2 ou inférieur, http://docs.python.org/release/2.5.2...-UserList.html

  3. #3
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 058
    Par défaut
    Je peux te donner un exemple simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Rectangle(object):
        def __init__(self, longueur, largeur):
            self.longueur=longueur
            self.largeur=largeur
        def aire(self):
            print self.longueur*self.largeur
    class Carre(Rectangle):
        def __init__(self, cote):
            Rectangle.__init__(self, cote, cote)
    Résultat :

    >>> r=Rectangle(12, 5)
    >>> r.aire()
    60
    >>> c=Carre(4)
    >>> c.aire()
    16

  4. #4
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    OK ! ça marche !
    merci

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 707
    Par défaut
    Salut,

    En sous-classant "list", il va être difficile de ne pas ré-écrire les méthodes pour réactualiser la longueur max.
    Le proxy est une bonne idée, mais je ne vois pas comment faire sans la petite indirection ci dessous.
    - W
    PS: Il y aura certainement des "bordures" à refaire suivant ce qu'on veut faire, mais l'idée est là

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    class B(object):
        def __init__(self, v=None):
            self._list = list(v)
            self._max_count = len(self._list)
     
        def __getattr__(self, key):
            def proxy(*args, **kwds):
                getattr(self._list, key)(*args, **kwds)
                self._max_count = max(self._max_count, len(self._list))
                return self
            return proxy
     
        def __str__(self):
            return 'max: %d, contents: %r' % (self._max_count, self._list)
     
    a = B([1, 2, 3])
    print a
    a.append([6])
    print a
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Si si ! c'est possible !
    Il suffit d'écrire les méthodes qui peuvent allonger la liste (dont le constructeur). Ici, je n'ai écrit que insert.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class my_list ( list ):
     
        def __init__(self,*arg):
            list.__init__(self,*arg)
            self.max_len = len( self )
     
        def insert (self,*args ):
            res = list.insert( self,*args )
            self.max_len = max( self.max_len,len( self ))
            return res
     
        def max (self):
            return self.max_len
     
    l = my_list( [1,2,3] )
    print l,len( l ),l.max()
    l.insert( 1,8 )
    print l,len( l ),l.max()
    del l[1:3]
    print l,len( l ),l.max()
    donne bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [1, 2, 3] 3 3
    [1, 8, 2, 3] 4 4
    [1, 3] 2 4
    A noter, la syntaxe d'appel du insert pour lever l'ambiguïté et éviter la récursion infinie.
    Mais ce qui me chiffonne, c'est comment différencier le self qui n'est qu'une liste (sur lequel on peut faire un len) et le self qui est mon instance de my_list avec le membre max_len en plus ?

  7. #7
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Et tu peux même surcharger les opérateurs:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class my_list ( list ):
     
        def __init__(self,*arg):
            list.__init__(self,*arg)
            self.max_len = len( self )
     
        def insert (self,*args ):
            res = list.insert( self,*args )
            self.max_len = max( self.max_len,len( self ))
            return res
        def __add__(self,other):
            self+=other
            self.max_len+=len(other)
            return self
     
        def max (self):
            return self.max_len
     
    l = my_list( [1,2,3] )
    print l,len( l ),l.max()
    l=l+[4,5]
    print l,len( l ),l.max()
    l.pop(0)
    print l,len( l ),l.max()
    l=l+l
    print l,len( l ),l.max()
    Le second argument de l'opérateur peut être soit une 'list' soit une 'mylist'
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 707
    Par défaut
    Si si ! c'est possible !
    Il suffit d'écrire les méthodes qui peuvent allonger la liste (dont le constructeur). Ici, je n'ai écrit que insert.
    Qui a dit le contraire? Juste que c'est ch... de trouver tous ces méthodes pour encapsuler l'appel au père permettant de recalculer la longueur...
    Non seulement, il n'est jamais certain de les avoir toutes re-écrites mais ce n'est pas utile.

    Mais ce qui me chiffonne, c'est comment différencier le self qui n'est qu'une liste (sur lequel on peut faire un len) et le self qui est mon instance de my_list avec le membre max_len en plus ?
    Les self sont identiques. Ce que vous essayez de différencier, ce sont les méthodes appliquées dessus: votre insert ou l'insert 'parent'?

    Dans le cas de "len", pas d'ambiguité tant que vous ne redéfinirez pas __len__ dans my_list.

    A noter, la syntaxe d'appel du insert pour lever l'ambiguïté et éviter la récursion infinie.
    Préférez super(my_list, self).insert(*args) à list.insert(self, *args)
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Classe dérivée de 'list' récalcitrante !
    Par sopsag dans le forum Général Python
    Réponses: 11
    Dernier message: 22/07/2010, 19h47
  2. Réponses: 1
    Dernier message: 24/01/2007, 16h00
  3. Réponses: 2
    Dernier message: 06/12/2005, 09h41
  4. Réponses: 4
    Dernier message: 20/11/2005, 05h48
  5. [POO] Un peu de mal avec les membres de ma classe
    Par Spack dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 04/11/2005, 03h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo