web-dev-qa-db-fra.com

Comment sous-classer Python list sans problèmes de type?

Je veux implémenter une classe de liste personnalisée dans Python en tant que sous-classe de list. Quel est l'ensemble minimal de méthodes dont j'ai besoin pour remplacer la base list afin d'obtenir une compatibilité de type complète pour toutes les opérations de liste?

Cette question suggère qu'au moins __getslice__ doit être remplacé. De plus amples recherches, également __add__ et __mul__ sera requis. J'ai donc ce code:

class CustomList(list):
    def __getslice__(self,i,j):
        return CustomList(list.__getslice__(self, i, j))
    def __add__(self,other):
        return CustomList(list.__add__(self,other))
    def __mul__(self,other):
        return CustomList(list.__mul__(self,other))

Les instructions suivantes fonctionnent comme vous le souhaitez, même sans les méthodes prioritaires:

l = CustomList((1,2,3))
l.append(4)                       
l[0] = -1
l[0:2] = CustomList((10,11))    # type(l) is CustomList

Ces instructions fonctionnent uniquement avec les méthodes de substitution dans la définition de classe ci-dessus:

l3 = l + CustomList((4,5,6))    # type(l3) is CustomList
l4 = 3*l                        # type(l4) is CustomList
l5 = l[0:2]                     # type(l5) is CustomList

La seule chose que je ne sais pas faire est de faire du retour de découpage étendu le bon type:

l6 = l[0:2:2]                   # type(l6) is list

Que dois-je ajouter à ma définition de classe pour obtenir CustomList comme type de l6?

Existe-t-il également d'autres opérations de liste autres que le découpage étendu, où le résultat sera de type list au lieu de CustomList?

33
silvado

Tout d'abord, je vous recommande de suivre les conseils de Björn Pollex (+1).

Pour surmonter ce problème particulier (type(l2 + l3) == CustomList), vous devez implémenter un --- __add__() :

   def __add__(self, rhs):
        return CustomList(list.__add__(self, rhs))

Et pour découpage étend :

    def __getitem__(self, item):
        result = list.__getitem__(self, item)
        try:
            return CustomList(result)
        except TypeError:
            return result

Je recommande aussi ...

pydoc list

... à votre demande. Vous verrez quelles méthodes list expose et cela vous donnera une bonne indication quant à celles que vous devez remplacer.

23
Johnsyweb

Vous devriez probablement lire ces deux sections de la documentation:

Edit: Afin de gérer le découpage étendu, vous devez faire votre __getitem__- la méthode gère les objets slice (voir ici , un peu plus bas).

20
Björn Pollex