2010-01-31 5 views
3

Comment fonctionne len sur Python?Comment ça marche?

Regardez cet exemple:

class INT(int): 
    pass 

class STR(str): 

    def __len__(self): 
     return INT(42) 

q = STR('how').__len__() 
print q, type(q) 
q = len(STR('how')) 
print q, type(q) 

La sortie est:

42 <class '__main__.INT'> 
42 <type 'int'> 

Comment puis-je gérer si len renvoie une instance INT?

Les réponses suggèrent que la seule solution est prépondérant len ​​

Ceci est ma mise en œuvre alternative. Cela ne semble pas très nuisible.

original_len = len 
def len(o): 
    l = o.__len__() 
    if isinstance(l, int): 
     return l 
    original_len(o) 
+8

Je ne veux pas faire ça. Pourquoi pensez-vous que c'est une bonne idée? – ironfroggy

+0

Je suis d'accord avec ironfroggy. Qu'est-ce que vous essayez réellement d'accomplir? Comment votre sous-classe int diffère-t-elle de int? – mzz

+0

Bien sûr, la classe INT dans l'exemple était juste un exemple. –

Répondre

3

Je ne pense pas que vous le pouvez, sauf si vous écrivez votre propre len. La ligne interne retourne toujours un int.

+0

Pourrait-il y avoir un problème si je remplace la longueur? –

+4

@Juanjo Conti: Vous confondez les autres développeurs qui lisent votre code et cela rend votre code plus difficile à réutiliser. –

3

Vous ne serez pas en mesure de. Au moins si vous voulez que ça fonctionne avec le reste de python. Voir la definition of len

appelé à mettre en œuvre la fonction intégrée len(). Devrait retourner la longueur de l'objet, un entier > = 0. En outre, un objet qui ne définit pas une méthode procédé et dont len() différent de zéro() renvoie zéro est considéré comme faux dans un contexte booléen .

Les italiques soulignent les miennes.

4

Ne faites pas cela. Vous devez apprendre quand la meilleure réponse est de ne pas faire ce que vous essayez de faire du tout. C'est l'une de ces fois.

2

Comme d'autres le disent, ne le faites pas. Voyez comment l'utilisation de cette classe ressemblerait:

length = len(s)  # the reader assumes `q` is an int. 
length.in_yards() # the reader is going WTF?! 

au lieu de violer les attentes du lecteur, pourquoi ne pas vous suffit d'ajouter une autre méthode:

s.length_in_yards() 

post-scriptum Ne résout pas cette question, mais si vous avez une bonne raison d'écrire des objets de type entier personnalisés, vous pouvez être intéressé par la méthode spéciale __index__ qui permet à un tel objet d'être directement utilisable pour l'indexation de séquences intégrées.