[Python] Implémentez votre propre classe de type liste à l'aide de collections.UserList

Lorsque je recherchais les collections de python, il n'y avait presque pas d'article sur collections.UserList, alors j'ai essayé de résumer comment l'utiliser.

Qu'est-ce que collections.UserList?

Le Document officiel dit:

Cette classe agit comme un wrapper pour les objets de liste. Ceci est utile comme classe de base pour votre propre classe de type liste, où vous pouvez remplacer des méthodes existantes ou en ajouter de nouvelles. De cette façon, vous pouvez ajouter un nouveau comportement à la liste.

Comme mentionné ci-dessus, ʻUserList est la classe de base pour créer votre propre classe de type liste. Une classe de type liste est une classe qui peut créer ʻappend et remove, et a un indexeur.

Essayez d'utiliser collections.UserList

À titre d'exemple, implémentons une liste ResettableList avec une méthode reset qui renvoie la liste à son état initial au moment du constructeur.

python


from collections import UserList


# collections.Hériter de UserList
class ResettableList(UserList):
    def __init__(self, initlist=None):
        super().__init__(initlist)
        self._initlist = initlist.copy()  #Gardez une copie de la liste d'initiation

    def reset(self):
        self.data = self._initlist.copy()  # self.data est la liste encapsulée


mylist = ResettableList([1, 2, 3])  #Passer la liste initiale au constructeur
print(f'mylist = {mylist}')
print(f'mylist.data = {mylist.data}')  # [non recommandé]Vous pouvez accéder à la liste interne avec des données

#Vous pouvez fonctionner comme une liste normale
print(f'mylist[1] = {mylist[1]}')
mylist.append(4)
print(f'mylist = {mylist}')
mylist.remove(1)
print(f'mylist = {mylist}')

mylist.reset()  #Revenir à l'état initial
print(f'mylist = {mylist}')

résultat

mylist = [1, 2, 3]
mylist.data = [1, 2, 3]
mylist[1] = 2
mylist = [1, 2, 3, 4]
mylist = [2, 3, 4]
mylist = [1, 2, 3]

ResettableList est un wrapper et stocke la liste dans la variable membre data. La méthode reset, qui a son propre comportement, est implémentée en manipulant ce self.data. De plus, dans l'exemple, la variable membre «data» est accessible de l'extérieur, mais ce comportement doit être évité car il peut provoquer des problèmes inattendus.

Pour illustrer cela, nous avons implémenté une liste ʻUnremovableList` qui ne peut pas supprimer des éléments.

python


from collections import UserList


#Exception lorsqu'une méthode qui supprime un élément est utilisée
class RemoveError(Exception):
    pass


class UnremovableList(UserList):
    #Remplacer la méthode qui supprime l'élément et déclencher une exception
    #Pour plus de simplicité, seule la suppression est remplacée ici
    def remove(self, item):
        raise RemoveError('Cannot remove')


mylist = UnremovableList([1, 2, 3])
print(f'mylist = {mylist}')

#Ne peut pas être supprimé
try:
    mylist.remove(1)
except RemoveError as e:
    print(f'RemoveError: {e}')
print(f'mylist = {mylist}')

# mylist.Je peux le supprimer lorsque j'accède aux données
mylist.data.remove(1)
print(f'mylist = {mylist}')

résultat

mylist = [1, 2, 3]
RemoveError: Cannot remove
mylist = [1, 2, 3]
mylist = [2, 3]

En accédant ainsi aux «données» de l'extérieur, vous pouvez supprimer les éléments qui auraient dû être interdits.

Il est normal d'hériter de list

Si vous voulez créer une classe de type liste, vous devriez pouvoir hériter de list. Y a-t-il un mérite d'hériter de collections.UserList au lieu de list? Dans le Document officiel, il est écrit comme suit.

Le besoin de cette classe a été partiellement remplacé par la possibilité de sous-classer directement à partir de la liste; cependant, il est plus facile d'utiliser cette classe car elle vous donne accès à la liste sous-jacente en tant qu'attribut. Il y a aussi.

"Cette classe" est ʻUserList. En résumé, "Vous pouvez hériter de liste, mais il est plus facile d'hériter de ʻUserList."

Voyons à quoi ressemblerait l'implémentation si nous héritions de list. Implémentez la ResettableList de l'exemple précédent de cette façon.

python


class ResettableList(list):
    def __init__(self, initlist=None):
        super().__init__(initlist)
        self._initlist = initlist.copy()

    def reset(self):
        self.clear()
        self.extend(self._initlist)

Vous devez travailler avec votre propre instance, contrairement à ce que vous avez hérité de ʻUserList`. Par conséquent, je l'ai implémenté en vidant la liste une fois et en ajoutant la liste initiale.

Une comparaison des deux est la suivante. (Seule la méthode reset est décrite)

python


#Version héritée de UserList
class ResettableList(UserList):
    def reset(self):
        self.data = self._initlist.copy()


#liste des versions héritées
class ResettableList(list):
    def reset(self):
        self.clear()
        self.extend(self._initlist)

Il est plus simple d'hériter de ʻUserList`.

en conclusion

Jusqu'à présent, j'ai résumé comment utiliser collections.UserList à ma manière. ʻUserList` a une structure qui contient une liste, mais qui ressemble à la liste elle-même lorsqu'elle est vue de l'extérieur. Je pense que cela sera également utile lors de l'extension des classes communes.

A propos, collections a aussi ʻUserDict et ʻUserString, qui sont similaires à ʻUserList`. C'est une classe de base pour créer respectivement des classes de type "dict" et "str". Je ne pense pas utiliser ces classes très souvent, mais j'aimerais les utiliser de manière appropriée dans ces situations.

Recommended Posts

[Python] Implémentez votre propre classe de type liste à l'aide de collections.UserList
python: utilisez votre propre classe pour numpy ndarray
[Road to Intermediate Python] Définissez dans votre propre classe
[Python] Créez votre propre bot LINE
[Python] journalisation dans votre propre module
Créez votre propre classe de structure graphique et son dessin avec python
Appelez votre propre bibliothèque partagée en langage C à partir de Python à l'aide de ctypes
Créez vos propres commandes Linux en Python
Implémenter __eq__ etc. de manière générique dans la classe Python
[LLDB] Créez votre propre commande avec Python
Utilisez facilement vos propres fonctions en Python
[Python] Empaquetez et distribuez vos propres modules
Tweet vos propres phrases en utilisant la chaîne de Markov
[Python] Enregistrez votre propre bibliothèque dans PyPI
Jusqu'à ce que vous installiez votre propre bibliothèque Python
[python] Comment ajouter RDF triple à votre propre serveur Fuseki en utilisant rdflib
Publiez votre propre bibliothèque Python sur Homebrew
Obtenez votre propre adresse IP en Python
Pièces jointes par e-mail à l'aide de votre compte gmail avec python.
Créez rapidement votre propre module avec setuptools (python)
Importez vos propres modules avec le développement Python de Grasshopper
[Python] classe, instance
"Kanrika" la classe python
À propos de python, classe
Commencez à utiliser Python
classe python, instance
Scraping à l'aide de Python
Les bases de #Python (classe)
Flux de création de votre propre package avec setup.py avec python
Mémo pour créer votre propre Box avec le Python de Pepper
Appelez votre propre bibliothèque de langage C avec Go en utilisant cgo
Créez votre propre Big Data en Python pour validation
[Introduction à l'application Udemy Python3 +] 66. Création de votre propre exception
Prenez votre propre utilisation maximale de la mémoire sous Linux et Python
Créez votre propre stéréogramme aléatoire (RDS) en Python.
Essayez d'améliorer votre propre quiz d'introduction avec Python
Appelons votre propre bibliothèque C ++ avec Python (Préférences)
[Blender x Python] Créez votre propre fonction et résumé jusqu'à présent
Utilisez CASA Toolkit dans votre propre environnement Python
Créez un environnement Python sur votre Mac en utilisant pyenv
Créez votre premier fichier GDSII en Python en utilisant gdspy
Appelez votre propre module python à partir du package ROS