Python >> Tutoriel Python >  >> Python

Méthode magique Python __index__()

__index__(self) de Python La méthode est appelée sur un objet pour obtenir sa valeur entière associée. L'entier retourné est utilisé dans le découpage ou comme base pour la conversion dans les fonctions intégrées bin() , hex() , et oct() . Le __index__() la méthode est également utilisée comme solution de secours pour int() , float() , et complex() lorsque leurs méthodes magiques correspondantes ne sont pas définies.

Syntaxe

object.__index__(self)

Nous appelons cela une "méthode Dunder" pour "D ouble Sous Méthode de score" (également appelée "méthode magique" ). Pour obtenir une liste de toutes les méthodes de dunder avec des explications, consultez notre article sur la feuille de triche de dunder sur ce blog.

Exemple personnalisé __index__()

Dans l'exemple suivant, vous créez une classe personnalisée Data et écrasez le __index__() méthode magique pour qu'elle renvoie un entier 2 sur un Data personnalisé objet. Nous imprimons ensuite le résultat des appels de fonction de six fonctions intégrées qui reposent toutes sur __index__() .

class Data:
    def __index__(self):
        return 2


x = Data()

# All those functions may use __index__():
print(bin(x))
print(oct(x))
print(hex(x))
print(complex(x))
print(int(x))
print(float(x))

La sortie de ces fonctions montre que toutes utilisent la valeur 2 pour leurs conversions, renvoyée par le __index__() méthode :

0b10
0o2
0x2
(2+0j)
2
2.0

Vous pouvez voir la même sortie lorsque vous transmettez la valeur entière 2 directement dans ces fonctions :

>>> bin(2)
'0b10'
>>> oct(2)
'0o2'
>>> hex(2)
'0x2'
>>> complex(2)
(2+0j)
>>> int(2)
2
>>> float(2)
2.0

Comment utiliser __index__() pour le découpage et l'indexation

Vous pouvez utiliser la méthode magique __index__() sur une classe personnalisée pour permettre aux objets de cette classe d'être utilisés dans une opération de découpage ou d'indexation sur un itérable. Python appellera en interne le __index__() pour obtenir l'entier associé à l'objet personnalisé. Cet entier est ensuite utilisé comme base pour l'opération de découpage et d'indexation.

Voir cet exemple où nous créons une classe personnalisée My_Integer et utiliser les objets de cette classe comme arguments pour l'opération de découpage sur une liste spécifique my_list .

class My_Integer:
    def __init__(self, i):
        self.i = i
        
    def __index__(self):
        return self.i


x = My_Integer(1)
y = My_Integer(8)
z = My_Integer(3)

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

print(my_list[x])
# 2

print(my_list[y])
# 9

print(my_list[x:y:z])
# [2, 5, 8]

Les objets x , y , z sont de type My_Integer mais ils peuvent toujours être utilisés pour les opérations d'indexation et de découpage, comme indiqué dans les trois dernières instructions d'impression.

Comment réparer "TypeError :__index__ a renvoyé un non-int (type …)"

Si vous remplacez le __index__() méthode afin qu'elle renvoie un type non entier x , Python lèvera un TypeError: __index__ returned non-int (type ...x) .

Vous pouvez le voir dans l'exemple suivant :

class Data:
    def __index__(self):
        return 'finxter'


x = Data()
print(int(x))

Sortie :

Traceback (most recent call last):
  File "C:\Users\xcent\Desktop\code.py", line 8, in <module>
    print(int(x))
TypeError: __index__ returned non-int (type str)

Pour corriger cette erreur, renvoyez simplement une valeur entière à partir du __index__() méthode comme ceci :

class Data:
    def __index__(self):
        return 42


x = Data()
print(int(x))
# 42

Références :

  • https://docs.python.org/3/reference/datamodel.html