2010-05-05 5 views
4

Y at-il un moyen d'avoir des opérateurs Python ligne "==" et ">" retourner ints au lieu de booléens. Je sais que je pourrais utiliser la fonction int (int(1 == 1)) ou ajouter 0 ((1 == 1) + 0) mais je me demandais s'il y avait un moyen facile de le faire. Comme lorsque vous voulez que la division renvoie des flottants, vous pouvez taper from __future__ import division. Y a-t-il un moyen de le faire avec des opérateurs qui retournent des ints? Ou pourrais-je faire une classe s'étendant __future__._Feature qui ferait ce que je veux?Opérateurs Python retournant des entrées

+1

Cela semble être une demande assez étrange, sans motivation claire. Voulez-vous expliquer un peu plus pourquoi vous croyez en avoir besoin? –

+0

Je fais un langage de programmation basé sur une pile. Si vous utilisez une valeur supérieure ou inférieure à celle-ci, deux éléments sont extraits de la pile et font quelque chose comme 'stack.push (pile.pop()> pile.pop())'. Si je voulais ensuite imprimer l'entier, il prendrait le haut de la pile et le convertirait en chaîne en utilisant 'str (stack.pop())' et l'imprimerait. Je voudrais que 1 ou 0 soit imprimé mais à la place il imprime "Vrai" ou "Faux". Cela crée des complications en faisant des choses comme si des déclarations. – None

+5

La modification des opérateurs fondamentaux dans Python n'est pas la solution. Vous ne voulez pas de Python (écrire votre propre fonction), ou vous voulez un comportement différent pour convertir des booléens en chaînes (écrire votre propre fonction). –

Répondre

1

Sur la base de ces précisions, vous pourriez changer votre opérateur de comparaison à quelque chose comme:

stack.push(1 if stack.pop() > stack.pop() else 0) 

Cela vous permet de convertir le résultat booléen de >-1 ou 0 que vous le souhaitez.

De même, faites attention à appeler deux fois stack.pop() dans la même expression. Vous ne savez pas (à coup sûr) dans quel ordre les arguments seront évalués, et différentes implémentations de Python peuvent très bien faire apparaître les arguments dans un ordre différent. Vous aurez besoin d'utiliser des variables temporaires:

x = stack.pop() 
y = stack.pop() 
stack.push(1 if x > y else 0) 
+0

J'ai fait les différents 'stack.pop()' s dans le code mais essayais de les compacter dans mon commentaire. Merci quand même. – None

+0

L'ordre d'évaluation des expressions est spécifié dans la référence de langage (http://docs.python.org/reference/expressions.html#evaluation-order). Cela dit, avoir des appels de fonction avec des effets secondaires à l'intérieur d'une expression non triviale est généralement une mauvaise idée. –

3

Vous ne pouvez pas remplacer les fonctions de comparaison intégrées. Dans un certain sens, les opérateurs de comparaison retournent déjà int. bool est une sous-classe de int, donc vous pouvez faire tout ce que vous pouvez faire pour un int. La question devient alors pourquoi voudriez-vous que les comparaisons retournent des objets int, pas des objets bool?

1

Vous pouvez avoir les opérateurs de comparaison de vos classes personnalisées retour tout ce que vous aimez - mettre en œuvre simplement les méthodes pertinentes (__eq__, __ne__, __gt__, __lt__, __ge__, __le__) pour revenir ce que vous voulez. Pour les objets que vous ne contrôlez pas, vous ne pouvez pas changer cela, mais il ne devrait pas y avoir besoin de: bools sont ints, en raison de the Liskov substitution principle. Le code qui remarque une différence entre le bool retourné par les méthodes __eq__ des types intégrés et tout autre entier utilise le résultat incorrect. Le module __future__ n'est pas pertinent ici; vous ne pouvez pas l'utiliser pour faire ce que vous voulez, vous ne pouvez l'utiliser que pour modifier les paramètres spécifiques qui ont été ajoutés à Python. Vous pouvez transformer la division en vraie division avec l'importation __future__ car c'est ce qui a été ajouté à Python. La seule façon d'ajouter plus d'importations __future__ est en modifiant Python lui-même.

1

Sur vos propres objets, il est facile de remplacer chaque opérateur de comparaison. Pour les built-ins, les méthodes override sont "en lecture seule" donc toutes mes tentatives pour les définir ne se déroulent pas.

>>> class foo: 
    def __lt__(self, other): 
     return cmp(5, other) 

>>> f = foo() 
>>> f<3 
1 
>>> f<7 
-1 
>>> f<5 
0 

>>> j="" 
>>> j.__lt__=lambda other: cmp(5, other) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
AttributeError: 'str' object attribute '__lt__' is read-only 
0

Jeter votre bool à un int?

>>> int(True)

1

>>> int(False)

0

Ou jeter que dans une str?

>>> str(int(True))

'1'

>>> str(int(False))

'0'

0

Non, vous ne pouvez pas. Lorsque Guido a unifié les types et les classes, il a trouvé un moyen de contourner le comportement des types intégrés (en raison de la façon dont il a implémenté les choses), mais il a déclaré qu'il s'agissait d'un bug et a comblé l'échappatoire. Changer le comportement des types intégrés (sauf pour votre exemple - l'importation de la division du futur, qui est là pour une bonne raison) est interdite.

Désolé, mais je ne trouve pas la liste de diffusion. Je m'en souviens cependant, car c'était assez intéressant.

Questions connexes