Résolue

__index__() dans une classe pour retourner un int

# Fonctions natives # Orienté objet

Salut ! Voilà un petit cas de figure que je ne comprend pas dans Python ! En gros je révisais un peu les built-in et je suis tombé là dessus :


class Number:
    value = 7
     
    def __int__(self):
        return self.value
 
data = Number()
print("number =", int(data))  # TypeError

---

class Number:
    value = 7
     
    def __index__(self):
        return self.value
 
data = Number()
print("number =", int(data))


Je ne comprend pas du tout le __index__(). Je comprend juste que cela permet de renvoyer un "int" mais je ne comprend pas comment. Le seul index() que je connais c'est la méthode pour les listes/tuples... pour retourner un indice. Si jamais quelqu'un à la réponse, je suis tout ouïe. Merci biennn !


Hugo



t'es sur que __index__ existe ?

de plus il te manque un i dans __int__, je ne pense pas que __int__ existe

Thibault houdon

Mentor

Salut Hugo :)


Alors c'est une méthode un peu spéciale avec plein de petites particularités.

Pour info, je ne me souviens pas avoir eu besoin de l'utiliser une seule fois en près de 10 ans de développement avec Python.


Déjà, c'est une méthode qui va servir de solution de repli si tu n'as pas implémenté les méthodes __int__ et __float__ et que tu essaies de convertir ta classe avec int ou float :


Sans définir les méthodes __int__ et __float__ :

class Number:
    def __index__(self):
        return 5

nbr = Number()
print(int(nbr))  # 5
print(float(nbr))  # 5.0


Si tu les définis, elles prendront le pas sur __index__ :

class Number:
    def __index__(self):
        return 5
def __int__(self):
        return 10
def __float__(self):
        return 15.5

nbr = Number()

print(int(nbr))  # 10
print(float(nbr))  # 15.5


Maintenant, son intérêt principal est de permettre à ton instance d'être utilisée dans des opérations de slicing ou pour récupérer un élément dans une liste. Des exemples seront plus parlants :


# On récupère le 1er élément de la liste car la fonction __index__ retourne 0
class Number:
    def __index__(self):
        return 0

nbr = Number()
langages = ["JavaScript", "PHP", "PatrickScript"]
print(langages[nbr])  # "JavaScript"
# On récupère le 2e élément de la liste car la fonction __index__ retourne 1
class Number:
    def __index__(self):
        return 1


nbr = Number()
langages = ["JavaScript", "PHP", "PatrickScript"]
print(langages[nbr])  # "PHP"
# Si tu n'implémentes pas __index__, tu ne peux pas utiliser ton instance pour récupérer un élément de ta liste et tu obtiens une erreur.
class Number:
    pass        

nbr = Number()
langages = ["JavaScript", "PHP", "PatrickScript"]
print(langages[nbr])  # TypeError: list indices must be integers or slices, not Number


Donc comme tu peux le voir, à moins d'avoir un besoin très spécifique, il est peu probable que tu aies besoin de l'utiliser :)


Bonne continuation !

Thib.

Merci Thib ! C'est beaucoup plus clair ! Après, comme tu le dis, pour une utilisation concrète, ça reste peu probable mais bon je pense qu'il est bien de comprendre le fonctionnement! Merci en tout cas ^^

Thierry Chappuis

Mentor

class Number:


    def __init__(self, value):
        self.value = value


    def __int__(self):
        print("dans __int__")
        return self.value


    def __index__(self):
        print("dans __index__")
        return self.value


a_number = Number(value=2)
a_list = [
    "zero",
    "one",
    "two",
    "three",
    "four"
]


int(a_number) # utiliser int() appelle a_number.__int__()
a_list[a_number] # utiliser a_number comme index d'une liste ou dans un slice appelle a_number.__index__() via operator.index()


   Les méthodes spéciales __int__() et __index__() sont ainsi appelées dans des contextes différents. Lorsque a_number est utilisé comme indice d'une séquence, la méthode __getitem__() de la séquence est appelée et cette dernière fait appel à operator.index() qui s'occupe finalement d'appeler a_number.__index__(). On retrouve plus ou moins le même mécanisme lorsque a_number est utilisé dans un slice.

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.