Python: créer une classe qui prend en charge l'affectation décompressée

Notez le résultat d'essais et d'erreurs, en vous demandant comment la substitution décompressée est réalisée.

Implémenter __getitem__ ()

>>> class MyTuple:
...     def __getitem__(self, key):
...         print(key)
...         if key < 3:
...             return str(key)
...         else:
...             raise IndexError
...

Il semble que la méthode __getitem__ () soit utilisée pour l'affectation décompressée [^ 1]. Le numéro d'index est passé comme clé.

[^ 1]: J'ai cherché un document, mais il n'est pas sorti tout de suite, alors j'ai expérimenté et je l'ai recherché.

Pour une mission ordinaire

__getitem__ () n'est pas appelé.

>>> x = MyTuple()
>>> x
<__main__.MyTuple object at 0x10a6bd850>

Pour des missions non emballées avec peu d'éléments

__Getitem__ () est appelé pour le nombre d'éléments sur le côté gauche + 1 fois. Si ʻIndexError ne se produit dans aucun des appels, on suppose qu'il y a beaucoup d'éléments sur le côté droit et ValueError` est généré.

>>> x, y = MyTuple()
0
1
2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

Pour les affectations non emballées avec un nombre d'éléments correspondant

__Getitem__ () est appelé pour le nombre d'éléments sur le côté gauche + 1 fois. Si ʻIndexError` se produit lors du dernier appel, les éléments gauche et droit sont considérés comme correspondant et l'affectation est réussie.

>>> x, y, z = MyTuple()
0
1
2
3
>>> x, y, z
('0', '1', '2')

Pour des missions non emballées avec de nombreux éléments

__Getitem__ () est appelé pour le nombre d'éléments sur le côté gauche + 1 fois. Si ʻIndexError` se produit au milieu de l'appel, on considère que l'élément sur le côté droit est manquant et l'affectation échoue.

>>> v, x, y, z = MyTuple()
0
1
2
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 4, got 3)

Pour les affectations déballées avec *

S'il y a un élément avec * sur le côté gauche, __getitem__ () sera appelé jusqu'à ce que ʻIndexError` se produise [^ 2]. Remplacez le résultat dans la variable sur le côté gauche d'une manière agréable.

[^ 2]: La bonne sensation est PEP 3132 - Déballage itérable étendu.

>>> a, *b = MyTuple()
0
1
2
3
>>> a, b
('0', ['1', '2'])

Un bel exemple

>>> *a, b = MyTuple()
0
1
2
3
>>> a, b
(['0', '1'], '2')

Cela vous donne l'impression de ne pas avoir à avoir un seul élément.

>>> *w, x, y, z = MyTuple()
0
1
2
3
>>> w, x, y, z
([], '0', '1', '2')
>>> w, *x, y, z = MyTuple()
0
1
2
3
>>> w, x, y, z
('0', [], '1', '2')
>>> w, x, *y, z = MyTuple()
0
1
2
3
>>> w, x, y, z
('0', '1', [], '2')
>>> w, x, y, *z = MyTuple()
0
1
2
3
>>> w, x, y, z
('0', '1', '2', [])

Mais si vous n'en avez pas deux, vous ne pouvez pas.

>>> *v, w, x, y, z = MyTuple()
0
1
2
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected at least 4, got 3)

Implémenter __iter__ ()

Vous pouvez également décompresser assign en implémentant __iter__ () au lieu de __getitem__ ().

>>> class MyTuple2():
...     def __iter__(self):
...         return iter([1, 2, 3])
...

L'implémentation est assez cassée, mais elle renvoie un itérateur pour un tableau à trois éléments. Cela fonctionne correctement.

>>> x, y, z = MyTuple2()
>>> x, y, z
(1, 2, 3)

Résumé

Soit __getitem__ () ou __iter__ () peut être utilisé, ce qui signifie que iterable est décompressé. Il peut être reformulé comme substituable.

Des exemples d'objets répétables incluent tous les types de séquence (liste, str, tuple, etc.), certains types non-séquence, tels que les objets dict et file, ou la méthode __iter__ () ou qui implémente la sémantique de séquence. Contient une instance de n'importe quelle classe qui a la méthode __getitem__ () .

Recommended Posts

Python: créer une classe qui prend en charge l'affectation décompressée
[Python] Créez un LineBot qui s'exécute régulièrement
Créer une page qui se charge indéfiniment avec python
[Note] Créez une classe de fuseau horaire sur une ligne avec python
Créer un environnement Python
J'ai essayé de créer une classe qui peut facilement sérialiser Json en Python
Créer une fausse classe qui triche également est une instance
Créez un chatbot prenant en charge la saisie gratuite avec Word2Vec
MALSS (introduction), un outil qui prend en charge l'apprentissage automatique en Python
Créer un plugin Wox (Python)
Créer une fonction en Python
Créer un dictionnaire en Python
Créer un répertoire avec python
Notez qu'il prend en charge Python 3
[Python] Créez un linebot qui dessine n'importe quelle date sur une photo
Créons un script qui s'enregistre avec Ideone.com en Python.
Création d'un script Python prenant en charge l'API e-Stat (ver.2)
Créez le code qui renvoie "A et prétendant B" en python
[MQTT / Python] Implémentation d'une classe qui fait Pub / Sub de MQTT en Python
Comment écrire une classe méta qui prend en charge à la fois python2 et python3
Créer une interface graphique python à l'aide de tkinter
Créer un conteneur DI avec Python
Créer un environnement Python sur Mac (2017/4)
Créez un environnement virtuel avec Python!
Créer un fichier binaire en Python
Créer un environnement python dans centos
Créer un framework de décorateur à usage général pour Python
5 façons de créer un chatbot Python
Créer une chaîne aléatoire en Python
[Python] Hériter d'une classe avec des variables de classe
Créer une instance d'une classe prédéfinie à partir d'une chaîne en Python
[Python / Django] Créer une API Web qui répond au format JSON
[Ev3dev] Créez un programme qui capture LCD (écran) en utilisant python
[LINE Messaging API] Créez un BOT qui se connecte à quelqu'un avec Python
J'essaierai de créer une structure de répertoires Python que je ne regretterai pas plus tard
Une classe qui résume les méthodes fréquemment utilisées dans l'api twitter (python)
[python] J'ai créé une classe qui peut écrire rapidement une arborescence de fichiers
Générer une collection de première classe en Python
[Python] Un programme qui crée des escaliers avec #
Créer un nouveau projet de calcul numérique Python
Classe qui atteint l'API de DMM
[Python] Comment rendre une classe itérable
Créez une image factice avec Python + PIL.
Créez un environnement python sur votre Mac
Créons un environnement virtuel pour Python
[Python] [LINE Bot] Créer un robot LINE de retour de perroquet
Créer un compteur de fréquence de mots avec Python 3.4
Technologie prenant en charge le descripteur Python #pyconjp
Créer un fichier deb à partir d'un package python
[GPS] Créer un fichier kml avec Python
Générer une classe à partir d'une chaîne en Python
Un monde typé qui commence par Python
Créons une base de données clients où le code QR est automatiquement émis en Python
Prend en charge Python 2.4
Créez un bot qui stimule les tendances Twitter
Un programme qui utilise Python pour lire des fichiers indésirables
[Python] Un programme qui arrondit le score
À partir d'un livre que les programmeurs peuvent apprendre (Python): Déclaration de classe (public / privé, etc.)