Notez le résultat d'essais et d'erreurs, en vous demandant comment la substitution décompressée est réalisée.
__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é.
__getitem__ ()
n'est pas appelé.
>>> x = MyTuple()
>>> x
<__main__.MyTuple object at 0x10a6bd850>
__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)
__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')
__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)
*
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)
__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)
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__ ()
ouqui implémente la sémantique de séquence. Contient une instance de n'importe quelle classe qui a la méthode __getitem__ ()
.
Recommended Posts